OpenCV_颜色直方图的计算、显示、处理、对比及反向投影
2011-10-13 20:02
603 查看
首先介绍一下直方图
一.用带权重的样本统计直方图
直方图Histogram,是一种常见的概率分布的非参数(区别于高斯分布,泊松分布等用参数表达概率密度的方法)表达方法。直方图可以看成概率密度分布的离散化表达方法。它的计算很简单,是一种投票的方法,就是每个样本往对应的小盒子(bin)里投一票。假设N个样本数据x量化为1~M之间的整数,那么Hist是M维数组,对应的直方图计算方法如下:
//initializing
for i=1:M
Hist[i] = 0;
end
//voting
for i = 1:N
Hist[x[i]] += 1 ;
end
为了表示成概率分布,需要Hist数组和为1:
//normalize
for j = 1:M
Hist[j] = Hist[j]/sum(Hist) ; //sum(Hist) = Hist[1] + Hist[2] + ... + Hist[M];
end
在这里sum(Hist)等于样本个数N。以上“投票+归一化”两个步骤,其实可以和成一步,即每个样本x[i]有一个对应的权重w[i]=1/N,投票的时候往小盒子里放的是权重:
//initializing
for i=1:M
Hist[i] = 0;
end
//voting
for i = 1:N
Hist[x[i]] += w[i] ;
end
这样得到数组Hist里的每个值都是一个0-1之间的小数,表示当x取这个值(数组对应的下标)时候的概率。
二.样本权重的变化影响直方图形状
如果想改变一个概率分布取曲线的形状,比如,在训练的时候要强调x[i]=3的样本,一种办法是增加这种样本的个数,使Hist[3]变大,另一种方法是增加和它对应的样本的权重w[i],让某些样本产生“一个顶俩”的效果,这两种方式都能起到改变概率分布的作用。
对人脸检测这类基于图像的目标检测方法,需要搜集大量样本进行离线的训练,样本要尽可能覆盖所有可能的情况,从而使所提取特征的概率分布具有代表性,当样本数趋向于无穷大的时候,概率分布就趋向于真实的分布情况。但通常在实际中,样本数总是有限的,这时就可以通过增加某些比较重要的样本的权重,来达到看起来是增加了某些样本数量的效果。
另外,直方图数组Hist的某个bin中的样本权重的改变,不应该仅仅影响当前的bin,也应该对周围相邻的bin造成影响。比如,在统计一个地区人群的身高分布的时候,如果只有一个样本x=1.65m,我们可以在Hist数组中对应1.6<=x<1.7这一个bin里投上一票,但是1.5<=x<1.6和1.7<=x<1.8两个bin的得票为0。其实不应该这样,根据身高应该是连续分布的这一假设,从样本x=1.65m可以安全地推断出世上也应该有身高1.59和1.71的人,这样左右两个相邻的bin的值就不应为0,应该也受到x=1.65m这个样本的影响,这种影响可以假设是服从高斯分布,即越远的bin受影响越小。这其实是另一种常见的概率密度估计的非参数方法,kernel density estimation(KDE)。我们的人脸检测应用由于样本足够多,所以没有考虑这一方法。也就是说,每个特征值在投票的时候,只对一个bin起作用,不影响相邻的那两个。
颜色直方图直观的显示了图像在色彩空间的分布状况,本文将讨论在OpenCv中跟直方图相关的一些基本操作,包括:计算、显示、处理、对比及反向投影.
直方图的计算、显示、处理
OpenCv中,可以用方法cvCalcHist方法计算图像的直方图。不过值得注意的是,该方法的第一个参数image是一个指向数组的IplImage* 类型指针。这允许利用多个图像通道。对于多通道图像(如HSV或者RGB),在调用函数cvCalcHist()之前,先要调用函数cvSplit()将图像分为单通道,此方法与宏cvCvtPixtoPlane等同,然后再选择需要参与直方图计算的通道。下面有几段计算直方图的代码,分别计算单通道(红色)直方图、色调和饱和度直方图。
如何在OpenCV中绘制一个直方图?下面是有关于绘制直方图实验的学习总结:
1.cvCreateHist(dim,&size,flag,**range,uniform):
dim为hist的维度;size为总分区间数;flag为标记图像是什么类型,是CV_HIST_ARRAY,还是CV_HIST_TREE,然后就可以选择如何保存数据,如果CV_HIST_ARRAY,就用CvMatND(多维密集数组);如果CV_HIST_TREE,就使用CvSparseMat(多维稀疏数组);range为每个维度的范围;uniform为归一化标识,这个还不是很好理解。
2.IplImage中有一个属性可以设置图像的原点坐标,0代表左上角,1代表左下角。(image->origin)
3.cvCalcHist(**imge,*hist):
image为统计图像,hist为直方图结构体
4.获取了直方图信息后,可以通过直方图结构体直接访问内部信息:
hist->type;hist->thresh[i][0]和hist->thresh[i][1]分别存储上阀值和下阀值。如果CV_HIST_ARRAY的话,可以通过((CvMatND*)hist->bins)->data.fl[i]获取统计值。不过OpenCV已经提供了一个很好的方法去查询,cvQueryHistValue_*D(hist,d...);
5.可以通过CV_RGB(R,G,B)的宏设置RGB颜色。
6.直方图的绘制,使用cvQueryHistValue_*D去获取统计值,然后绘制在一个创建好的图像中。可以通过cvLine或者cvRectangle方法。
7.还可以通过设置range的范围来获取有需要的区域,如果这样的话,最好在画直方图的时候,计算好每个区间的width值。
8.cvGetMinMaxValue(hist,*min,*max,*minindex,*maxindex):
min和max必须为float类型,minindex和maxindex为最小最大值的位置
9.cvRound方法:四舍五入
10.从HSV颜色转换为RGB颜色:
IplImage* hsv_color = cvCreateImage(cvSize(1,1),8,3);
IplImage* rgb_color = cvCreateImage(cvSize(1,1),8,3);
cvSet2D(hsv_color,0,0,cvScalar(h*180.f/h_bins,s*255.f/s_bins,255,0));
cvCvtColor(hsv_color,rgb_color,CV_HSV2BGR);
CvScalar color = cvGet2D(rgb_color,0,0);
具体代码如下:
View Code
感谢您耐心看完本文,希望对您有所帮助。
一.用带权重的样本统计直方图
直方图Histogram,是一种常见的概率分布的非参数(区别于高斯分布,泊松分布等用参数表达概率密度的方法)表达方法。直方图可以看成概率密度分布的离散化表达方法。它的计算很简单,是一种投票的方法,就是每个样本往对应的小盒子(bin)里投一票。假设N个样本数据x量化为1~M之间的整数,那么Hist是M维数组,对应的直方图计算方法如下:
//initializing
for i=1:M
Hist[i] = 0;
end
//voting
for i = 1:N
Hist[x[i]] += 1 ;
end
为了表示成概率分布,需要Hist数组和为1:
//normalize
for j = 1:M
Hist[j] = Hist[j]/sum(Hist) ; //sum(Hist) = Hist[1] + Hist[2] + ... + Hist[M];
end
在这里sum(Hist)等于样本个数N。以上“投票+归一化”两个步骤,其实可以和成一步,即每个样本x[i]有一个对应的权重w[i]=1/N,投票的时候往小盒子里放的是权重:
//initializing
for i=1:M
Hist[i] = 0;
end
//voting
for i = 1:N
Hist[x[i]] += w[i] ;
end
这样得到数组Hist里的每个值都是一个0-1之间的小数,表示当x取这个值(数组对应的下标)时候的概率。
二.样本权重的变化影响直方图形状
如果想改变一个概率分布取曲线的形状,比如,在训练的时候要强调x[i]=3的样本,一种办法是增加这种样本的个数,使Hist[3]变大,另一种方法是增加和它对应的样本的权重w[i],让某些样本产生“一个顶俩”的效果,这两种方式都能起到改变概率分布的作用。
对人脸检测这类基于图像的目标检测方法,需要搜集大量样本进行离线的训练,样本要尽可能覆盖所有可能的情况,从而使所提取特征的概率分布具有代表性,当样本数趋向于无穷大的时候,概率分布就趋向于真实的分布情况。但通常在实际中,样本数总是有限的,这时就可以通过增加某些比较重要的样本的权重,来达到看起来是增加了某些样本数量的效果。
另外,直方图数组Hist的某个bin中的样本权重的改变,不应该仅仅影响当前的bin,也应该对周围相邻的bin造成影响。比如,在统计一个地区人群的身高分布的时候,如果只有一个样本x=1.65m,我们可以在Hist数组中对应1.6<=x<1.7这一个bin里投上一票,但是1.5<=x<1.6和1.7<=x<1.8两个bin的得票为0。其实不应该这样,根据身高应该是连续分布的这一假设,从样本x=1.65m可以安全地推断出世上也应该有身高1.59和1.71的人,这样左右两个相邻的bin的值就不应为0,应该也受到x=1.65m这个样本的影响,这种影响可以假设是服从高斯分布,即越远的bin受影响越小。这其实是另一种常见的概率密度估计的非参数方法,kernel density estimation(KDE)。我们的人脸检测应用由于样本足够多,所以没有考虑这一方法。也就是说,每个特征值在投票的时候,只对一个bin起作用,不影响相邻的那两个。
颜色直方图直观的显示了图像在色彩空间的分布状况,本文将讨论在OpenCv中跟直方图相关的一些基本操作,包括:计算、显示、处理、对比及反向投影.
直方图的计算、显示、处理
OpenCv中,可以用方法cvCalcHist方法计算图像的直方图。不过值得注意的是,该方法的第一个参数image是一个指向数组的IplImage* 类型指针。这允许利用多个图像通道。对于多通道图像(如HSV或者RGB),在调用函数cvCalcHist()之前,先要调用函数cvSplit()将图像分为单通道,此方法与宏cvCvtPixtoPlane等同,然后再选择需要参与直方图计算的通道。下面有几段计算直方图的代码,分别计算单通道(红色)直方图、色调和饱和度直方图。
如何在OpenCV中绘制一个直方图?下面是有关于绘制直方图实验的学习总结:
1.cvCreateHist(dim,&size,flag,**range,uniform):
dim为hist的维度;size为总分区间数;flag为标记图像是什么类型,是CV_HIST_ARRAY,还是CV_HIST_TREE,然后就可以选择如何保存数据,如果CV_HIST_ARRAY,就用CvMatND(多维密集数组);如果CV_HIST_TREE,就使用CvSparseMat(多维稀疏数组);range为每个维度的范围;uniform为归一化标识,这个还不是很好理解。
2.IplImage中有一个属性可以设置图像的原点坐标,0代表左上角,1代表左下角。(image->origin)
3.cvCalcHist(**imge,*hist):
image为统计图像,hist为直方图结构体
4.获取了直方图信息后,可以通过直方图结构体直接访问内部信息:
hist->type;hist->thresh[i][0]和hist->thresh[i][1]分别存储上阀值和下阀值。如果CV_HIST_ARRAY的话,可以通过((CvMatND*)hist->bins)->data.fl[i]获取统计值。不过OpenCV已经提供了一个很好的方法去查询,cvQueryHistValue_*D(hist,d...);
5.可以通过CV_RGB(R,G,B)的宏设置RGB颜色。
6.直方图的绘制,使用cvQueryHistValue_*D去获取统计值,然后绘制在一个创建好的图像中。可以通过cvLine或者cvRectangle方法。
7.还可以通过设置range的范围来获取有需要的区域,如果这样的话,最好在画直方图的时候,计算好每个区间的width值。
8.cvGetMinMaxValue(hist,*min,*max,*minindex,*maxindex):
min和max必须为float类型,minindex和maxindex为最小最大值的位置
9.cvRound方法:四舍五入
10.从HSV颜色转换为RGB颜色:
IplImage* hsv_color = cvCreateImage(cvSize(1,1),8,3);
IplImage* rgb_color = cvCreateImage(cvSize(1,1),8,3);
cvSet2D(hsv_color,0,0,cvScalar(h*180.f/h_bins,s*255.f/s_bins,255,0));
cvCvtColor(hsv_color,rgb_color,CV_HSV2BGR);
CvScalar color = cvGet2D(rgb_color,0,0);
具体代码如下:
View Code
int main( int argc, char** argv ) { IplImage *src, *templ,*ftmp[6]; //ftmp is what to display on int i; //Read in the template to be used for matching: if((templ=cvLoadImage("flower1.jpg", 1))== 0) { printf("Error on reading template /n"); return(-1); } //Read in the source image to be searched: if((src=cvLoadImage("flower.jpg", 1))== 0) { printf("Error on reading src image /n"); return(-1); } int patchx = templ->width; int patchy = templ->height; int iwidth = src->width - patchx + 1; int iheight = src->height - patchy + 1; for(i=0; i<6; ++i){ ftmp[i] = cvCreateImage( cvSize(iwidth,iheight),32,1); } //DO THE MATCHING OF THE TEMPLATE WITH THE IMAGE for(i=0; i<6; ++i){ cvMatchTemplate( src, templ, ftmp[i], i); // double min,max; // cvMinMaxLoc(ftmp,&min,&max); cvNormalize(ftmp[i],ftmp[i],1,0,CV_MINMAX); } //DISPLAY cvNamedWindow( "Template", 0 ); cvShowImage( "Template", templ ); cvNamedWindow( "Image", 0 ); cvShowImage( "Image", src ); cvNamedWindow( "SQDIFF", 0 ); cvShowImage( "SQDIFF", ftmp[0] ); cvNamedWindow( "SQDIFF_NORMED", 0 ); cvShowImage( "SQDIFF_NORMED", ftmp[1] ); cvNamedWindow( "CCORR", 0 ); cvShowImage( "CCORR", ftmp[2] ); cvNamedWindow( "CCORR_NORMED", 0 ); cvShowImage( "CCORR_NORMED", ftmp[3] ); cvNamedWindow( "CCOEFF", 0 ); cvShowImage( "CCOEFF", ftmp[4] ); cvNamedWindow( "CCOEFF_NORMED", 0 ); cvShowImage( "CCOEFF_NORMED", ftmp[5] ); //LET USER VIEW RESULTS: cvWaitKey(0); return 0; }
感谢您耐心看完本文,希望对您有所帮助。
相关文章推荐
- OpenCV_颜色直方图的计算、显示、处理、对比及反向投影【转】
- OpenCV_颜色直方图的计算、显示、处理、对比及反向投影
- OpenCV_颜色直方图的计算、显示、处理、对比及反向投影
- 颜色直方图的计算、显示、处理、对比及反向投影(How to Use Histogram? Calculate, Show, Process, Compare and BackProject)
- 颜色直方图的计算、显示、处理、对比及反向投影(How to Use Histogram? Calculate, Show, Process, Compare and BackProject)
- OpenCV之imgproc 模块. 图像处理(4)直方图均衡化 直方图计算 直方图对比 反向投影 模板匹配
- OpenCV_颜色直方图的计算、显示、处理、对比及反向投影
- OpenCV_颜色直方图的计算、显示、处理、对比及反向投影
- OpenCV Python教程(3)(4)(5): 直方图的计算与显示 形态学处理 初级滤波内
- OPENCV直方图计算原理及反向投影检测原理
- OPENCV直方图计算原理及反向投影检测原理
- 直方图的均衡、直方图的反向投影算法,opencv鼠标和键盘处理事件
- Python-OpenCV 处理图像(四):图像直方图和反向投影
- opencv中直方图的反向投影之cvCalcBackProjectPatch
- 直方图进阶应用(对比,块反向投影)
- opencv 直方图反向投影
- 【OpenCV】显示HSV模型中H分量的颜色直方图
- 【OpenCV】直方图(二)反向投影
- OpenCV统计应用-直方图反向投影
- Python OpenCV学习笔记之:图像直方图反向投影(backprojection)原理简单实现