opencv版本:2.3.1
配置环境:openCV学习笔记(一):opencv2.3.1和vs2010安装配置
#包括
#包括
#包括
#包括
使用命名空间 cv;
使用命名空间 std;
int main()
{
char *imageSrc = "I:\\OpenCV Learning\\picture\\sumpalace.jpg";
垫图像 = imread(imageSrc,1);
/****************************************/
//Mat greyImage = imread(imageSrc,0);
/****************************************/
if(!www.gsm-guard.net)
{
cout<<"错误"< 返回-1; } imshow("原图",图片); 矢量 split(图像,rgbPlanes); /****************************************/ /*rgbPlanes向量(递增数组),通过split()函数,将图像的R、G、B通道分别添加到rgbPlanes[0]、rgbPlanes[1]、rgbPlanes[2] /****************************************/ //Mat *grayImage = &grayImage0; /****************************************/ int histSize = 256; //R、G、B取值范围为[0,255] 浮点范围[] = {0,255}; const float *histRange = {范围}; //三个矩阵,分别保存R、G、B直方图 垫红色Hist、绿色Hist、蓝色Hist; /****************************************/ //Mat greyHist; /****************************************/ //计算R、G、B直方图,见下文calcHist()函数的参数分析 calcHist( &rgbPlanes[0], 1, 0, Mat(), redHist, 1, &histSize, &histRange,true,false); calcHist( &rgbPlanes[1], 1, 0, Mat(), greenHist, 1, &histSize, &histRange,true,false); calcHist( &rgbPlanes[2], 1, 0, Mat(), blueHist, 1, &histSize, &histRange,true,false); /****************************************/ //calcHist(&grayImage,1,0,Mat(),grayHist,1,&histSize,&histRange,true,false); /****************************************/ //定义显示直方图的画布 int histWidth = 400; int histHeight = 400; int binWidth = cvRound((double)histWidth/histSize); Mat histImage(histWidth,histHeight,CV_8UC3,标量(0,0,0)); //后面进行归一化处理参见normalize()函数的参数分析 标准化(redHist,redHist,0,histImage.rows,NORM_MINMAX,-1,Mat()); 标准化(greenHist,greenHist,0,histImage.rows,NORM_MINMAX,-1,Mat()); 标准化(blueHist,blueHist,0,histImage.rows,NORM_MINMAX,-1,Mat()); /****************************************/ //标准化(grayHist,grayHist,0,histImage.rows,NORM_MINMAX,-1,Mat()); /****************************************/ //绘制直方图 for( int i = 1; i < histSize; i++ ) { line( histImage, Point( binWidth*(i-1), histHeight - cvRound(www.gsm-guard.net 点( binWidth*(i), histHeight - cvRound(www.gsm-guard.net 标量( 0, 0, 255), 2, 8, 0 ); // 矩形(histImage,Point( binWidth*(i-1), histHeight), // 点( binWidth*(i-1), histHeight - cvRound(www.gsm-guard.net line( histImage, Point( binWidth*(i-1), histHeight - cvRound(www.gsm-guard.net 点( binWidth*(i), histHeight - cvRound(www.gsm-guard.net 标量( 0, 255, 0), 2, 8, 0 ); line( histImage, Point( binWidth*(i-1), histHeight - cvRound(www.gsm-guard.net 点( binWidth*(i), histHeight - cvRound(www.gsm-guard.net 标量( 255, 0, 0), 2, 8, 0 ); /****************************************/ /*line( histImage, Point( binWidth*(i-1), histHeight - cvRound(www.gsm-guard.net 点( binWidth*(i), histHeight - cvRound(www.gsm-guard.net 标量( 255, 255, 255), 2, 8, 0 );*/ /****************************************/ } // 显示直方图 imshow("直方图", histImage ); waitKey(); 返回0; } 运行结果: 说明(此部分来自http://www.gsm-guard.net/opencvdoc/2.3.2/html/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.html) ——calcHist()函数 参数说明如下: &rgbPlanes[0]:?输入数组(或数组集) 1:输入数组的数量(这里我们使用单通道图像,也可以输入数组集) 0:需要的通道(dim)索引要统计,这里只统计灰度(而且每个数组都是单通道),所以就写0即可。 Mat(): Mask(0表示忽略像素),如果不定义则不使用mask redHist: Matrix存储直方图1:直方图维度histSize:?每个维度的 bin 数量 histRange:?各尺寸的取值范围是否一致?和?accumulate:bin大小相同,直方图痕迹清晰 ——normalize()函数 该函数接受以下参数: redhist:?输入数组 redhist:?归一化输出数组(支持就地计算)0?和?histImage.rows:这里是归一化后的值限制?redhist?NORM_MINMAX:?归一化方法(示例中指定的方法将值缩放到上面指定的范围) -1:?表示归一化输出数组与输入数组 Mat() 类型相同:?可选面罩 实验环境:VS2010 + OpenCV2.4.9.0 #包括 #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" 使用命名空间 std; 使用命名空间 cv; void showHistogram(Mat &src, int bins,char* wndName) { int histSize[] = {bins}; 浮点范围[] = {0,bins}; const float* 范围[] = {范围}; MatND 历史记录; int 通道[] = {0}; calcHist(&src, 1, 通道, Mat(), hist, 1, histSize, 范围, true, false); 双 maxVal; minMaxLoc(hist, 0, &maxVal, 0, 0); int 比例 = 2; //直方图大小(宽度) int histHeight = 256; Mat histImage = Mat::zeros(histHeight,bins * scale,CV_8UC1); for(int i = 0; i < bin; i++) { float binVal = www.gsm-guard.net int 强度 = cvRound(binVal * histHeight/maxVal); 矩形(histImage,Point(i * 尺度,histHeight - 1), 点((i + 1)*尺度 - 1,histHeight - 强度),CV_RGB(255,255,255)); } namedWindow(wndName,CV_WINDOW_AUTOSIZE); imshow(wndName,histImage); } int main(int argc,char** argv) { 垫 src,dst; char* source_window = "源图像"; char* equalized_window = "均衡图像"; src = imread("lena.jpg"); if(!www.gsm-guard.net) { cerr <<“读取图像失败!” <<结束; 出口(1); } cvtColor(src,src,CV_BGR2GRAY); equalizeHist(src,dst); namedWindow(source_window,CV_WINDOW_AUTOSIZE); imshow(source_window,src); namedWindow(equalized_window,CV_WINDOW_AUTOSIZE); imshow(equalized_window,dst); //显示直方图 int bin = 256; showHistogram(src, bins,"原始图像历史"); showHistogram(dst, bins,"均衡图像历史"); waitKey(0); 返回0; } 实验结果: 原图: 原始直方图: 直方图均衡结果: 均衡后直方图: 原始来源:http://www.gsm-guard.net/tornadomeet/archive/2012/05/03/2480824.html 直方图在CV领域随处可见,因为它们的功能在CV算法的实现中至关重要。 Opencv库还集成了很多关于直方图的功能,比如直方图计算、均衡、归一化、相似度比较等。 为了体验这些功能,我做了一个小实验。功能为:打开相机,用鼠标选中一个方框,将方框内的图像作为标准图像,计算其直方图并显示;然后继续用鼠标选中方框,方框内图像的直方图 计算图像与标准图像的相似度,并在终端输出计算结果。值越大,相似度越大。 项目环境:opencv2.3.1+vs2010。 // hist_test.cpp:定义控制台应用程序的入口点。 // #include "stdafx.h" #包括 #包括 #包括 #包括 #包括 使用命名空间 cv; 使用命名空间 std; int nFrame_num=0; 布尔暂停=假; 布尔跟踪= false; Rect preselectROI,selectROI;//用于存储手选的矩形 bool comp=true; Mat rhist,ghist,bhist; int 通道[]={0,1,2}; //const int histsize[]={256,256,256}; const int histsize[]={16,16,16}; const int histsize1=16; 浮动排列[]={0,255}; 浮动田庄[]={0,255}; 浮动范围[]={0,255}; 浮点范围[]={0,255}; const float *ranges1={range};//这里的ranges相当于双指针 const float *ranges[]={rranges,granges,branges};//ranges是双指针,前面必须加const,即常量不能改变,提高了可读性和鲁棒性节目 //const float *ranges[]={{0,255},{0,255},{0,255}}; void onMouse(int event,int x,int y,int,void *) { if(事件==CV_EVENT_LBUTTONDOWN) { selectROI.x=x; selectROI.y=y; 跟踪=假; } else if(事件==CV_EVENT_LBUTTONUP) { selectROI.width=x-selectROI.x; selectROI.height=y-selectROI.y; 跟踪=true; comp=true; nFrame_num++;//选择后第一帧才是真实的 if(nFrame_num>=10)nFrame_num=10;//防止nFrame_num溢出 } } int main(int argc, const char* argv[]) { 垫架,img; Mat staRoiHist; MatND RoiHist; int DRAW_H=400,DRAW_W=400; Mat draw(DRAW_W,DRAW_H,CV_8UC3,Scalar(0,0,0));//创建一张图片来显示直方图,纯黑色背景 int DRAW_BIN_W=cvRound(DRAW_W/histsize1); /****打开相机****/ 视频采集摄像头(0); if(!cam.isOpened()) 返回-1; /****鼠标捕捉****/ namedWindow("相机",1); namedWindow("rgb_hist",1); setMouseCallback("camera",onMouse,0);//这里使用了面向对象的思想。只要有鼠标移动,就会调用鼠标响应函数 同时(1) { if(!pause)//暂停键只控制视频的读取 { 凸轮>>框架; if(frame.empty()) 断裂; //break这里是一个while语句,一般是for或者while语句,不要理解为if语句 } /* if(1==nFrame_num) { }*/ if(追踪) { Mat RoiImage(frame,selectROI); /**************************************************** ****************************************************** *************************/ /**** calcHist():计算图像块的直方图矩阵****/ /****calcHist(),第一个参数为原数组区域列表;第二个参数是要计算的原始数组的数量;参数3为需要统计的通道索引个数;参数4为操作掩码****/ /****第五个参数是存储目标直方图矩阵;参数6为需要计算的直方图的维度;参数7是每个维度的bin数;参数8为各维度的值****/ /****参数10是一个标志,表示各个bin的大小是否相同,默认为1,即各个bin的大小都相同;参数11是直方图建立时清除内存痕迹的标志,默认为0,即清除****/ /**************************************************** ****************************************************** *************************/ calcHist(&RoiImage,1,channels,Mat(),RoiHist,3,histsize,ranges);//原始数组区域RoiImage,1个源,要统计的通道索引为{0,1,2}, //目标直方图RoiHist,3个维度,每个维度的bin数histsize,取值范围为 //范围,实际上计算出的目标矩阵类似于一维矩阵。 /**************************************************** ****************************************************** *************************/ /**** Normalize():按照一定的范数或数值范围对数组进行归一化****/ /**** Normalize(),参数1代表需要归一化的数组;参数2为归一化后的目标数组;参数3表示输出值的最小值/最大值或输出值的范数;****/ /**** 参数4代表输出值的最小值/最大值;参数 5 表示标准化数组中使用的标准化类型。默认值是使用L2范数;参数6是相应元素的掩码。矩阵****/ /**** 默认值为空,即不使用掩码操作****/ /**************************************************** ****************************************************** *************************/ normalize(RoiHist,RoiHist);//使用L2范数对RoiHist直方图进行就地归一化 vector split(RoiImage,rgb_planes);//将rgb图像分解为rgb_planes的各个分量 calcHist(&rgb_planes[0],1,0,Mat(),rhist,1,&histsize1,&ranges1); normalize(rhist,rhist,0,DRAW_H,NORM_MINMAX);//对最大值和最小值进行归一化 calcHist(&rgb_planes[1],1,0,Mat(),ghist,1,&histize1,&ranges1); 标准化(ghist,ghist,0,DRAW_H,NORM_MINMAX); calcHist(&rgb_planes[2],1,0,Mat(),bhist,1,&histize1,&ranges1); 标准化(bhist,bhist,0,DRAW_H,NORM_MINMAX); if(nFrame_num==1) { //预选ROI=selectROI; preselectROI.x=selectROI.x; preselectROI.y=selectROI.y; preselectROI.width=selectROI.width; preselectROI.height=selectROI.height; staRoiHist=RoiHist.clone();//第一次选择目标作为标准模板目标 } else if(nFrame_num>1&&comp==true) { /**************************************************** ****************************************************** *************************/ /****compareHist():比较两个直方图的相似度****/ /****compareHist(),参数1为直方图1,用于比较相似度;参数2为直方图2,用于比较相似度;参数3是相似度的计算方法。有四种类型,****/ /**** 分别为 CV_COMP_CORREL、CV_COMP_CHISQR、CV_COMP_INTERSECT、CV_COMP_BHATTACHARYYA ****/ /**************************************************** ****************************************************** *************************/ double distence=compareHist(staRoiHist,RoiHist,CV_COMP_INTERSECT);//计算后面的选择与本次选择的相似度,使用INTERSECT,值越大越相似 printf("与第一个选定图像区域的相似度为:%f\n",distence);//数组越大,相似度越大 //显示直方图 for(int i=1;i { //画直线要注意两点。因为图片的原点在左上角,而直方图坐标系的原点在左下角,所以需要从直方图绘制的高度中减去高度值,一维直方图为采取。绘图时只能使用 at 运算符 线(绘制,点(DRAW_BIN_W*(i-1),DRAW_H-cvRound(www.gsm-guard.net 线(绘制,点(DRAW_BIN_W*(i-1),DRAW_H-cvRound(www.gsm-guard.net 线(绘制,点(DRAW_BIN_W*(i-1),DRAW_H-cvRound(www.gsm-guard.net } imshow("rgb_hist",draw); draw=Mat::zeros(DRAW_W,DRAW_H,CV_8UC3);//每次绘制直方图后清0 comp=false; } 矩形(frame,selectROI,Scalar(0,255,0),2,8);//手动选择一次显示一次 }//结束追踪 矩形(frame,preselectROI,Scalar(0,0,255),5,8);//初始选定目标不变 imshow("相机",frame); //键盘响应 char c = (char)waitKey(10); if( c == 27 ) 断裂; 开关(c) { case 'p'://暂停键 暂停=!暂停; 断裂; 默认: ; } }//结束同时; 返回0; } 实验结果: 所选框中的模板用红色框标记,其他要比较的模板用绿色框标记。 模板图像块的简单直方图(rgb单独绘制)如下所示: 第一张对比结果图: 第二张对比结果图 第三张对比结果图(选中的两个框基本重叠): 第三张对比相似度结果相关推荐
《崩坏3》逃出生天关卡怎么打
《战地指挥官》战役第一章通关
【java】 获取计算机信息和
C# 获取本地CPU序列号、M
如何用keil5注释中文(如何
vs2010直方图定义参数_O
Docker搭建自己的本地镜像
如何使用docker+devp
Ubuntu16.04.4LT
用于 CSS 定位的三个选择器
测试即可使用, DreamWe
徐州游戏编程培训价格,中润新能
《都市天际线 2》全新游戏日志
转转中虚拟数字的实践与应用
GPU容器虚拟化新能力发布及全
《成都seo》网站SEO如何发
《长沙seo》如何写出容易被收
laravel 查询构造函数中
如何判断laravel查询数据
oracle行到列分析函数
Linux下C语言对php的扩
全网最全面的“分布式微服务权限
SpringCloud 五个核
SpringCloud 五个核
0条大师的评论