主要涉及两个函数:
CvHistogram cvCalcHist
#include<stdio.h> #include<cv.h> #include<highgui.h> int main() { int hist_size[]={16,16,16}; float range[]={0,255}; float *ranges[]={range}; int i,j,bin_w; float max_value,min_value; int min_idx, max_idx; char *name[3]={"b","g","r"}; double mean=0,variance=0; IplImage* img=cvLoadImage("b.jpg",1); IplImage *pImage=NULL; IplImage *pImg[3]; pImg[0]=cvCreateImage(cvGetSize(img),8,1); pImg[1]=cvCreateImage(cvGetSize(img),8,1); pImg[2]=cvCreateImage(cvGetSize(img),8,1); cvSplit(img,pImg[0],pImg[1],pImg[2],NULL); pImage=cvCloneImage(img); CvRect rect= cvRect(0,0,500,600); cvSetImageROI(pImage,rect); //创建一个图像用来存放直方图 IplImage *histImage[3]; CvHistogram *hist[3]; for(j=0;j<3;j++){ histImage[j]=cvCreateImage(cvSize(320,200),8,3); //cvZero(histImage[j]); hist[j]=cvCreateHist(1,&hist_size[j],CV_HIST_ARRAY,ranges,1); //计算直方图并作用到hist变量中 cvCalcHist(&pImg[j], hist[j], 0, NULL); //得到直方图的最值及标号 cvGetMinMaxHistValue(hist[j],&min_value,&max_value,&min_idx,&max_idx); //缩放其最大值和最小值让其融入图像 cvScale(hist[j]->bins,hist[j]->bins,((double)histImage[j]->height)/max_value,0); //设置所有的直方图的数值为255 cvSet(histImage[j],cvScalarAll(255),0); //建一个比例因子 沿宽度释放 bin_w=cvRound((double)histImage[j]->width/hist_size[j]); mean=0; for(i=0;i<hist_size[j];i++) { CvScalar scalar=cvScalarAll(0); scalar.val[j]=(i*255/hist_size[j]); cvRectangle(histImage[j],cvPoint(i*bin_w,histImage[j]->height), cvPoint((i+1)*bin_w,histImage[j]->height-cvRound(cvGetReal1D(hist[j]->bins,i))),scalar,-1,8,0); float *bins=cvGetHistValue_1D(hist[j],i); //增加均值 mean+=bins[0]; //std::cout<<bins[0]<<" "<<bins[1]<<std::endl; //printf("%d %d\n",bins[0],bins[1]); } cvNamedWindow(name[j],0); cvShowImage(name[j],histImage[j]); mean/=hist_size[j]; //根据均值计算变化量 for(i=0;i<hist_size[j];i++) { float* bins=cvGetHistValue_1D(hist[j],i); variance+=pow((bins[0]-mean),2); } variance/=hist_size[j]; printf("histgram Mean:%f\n",mean); } //创建窗口 cvNamedWindow("Original",0); cvShowImage("Original",pImage); cvWaitKey(0); cvReleaseImage(&img); for(j=0;j<3;j++){ cvDestroyWindow(name[j]); cvReleaseImage(&pImg[j]); cvReleaseImage(&histImage[j]); cvReleaseHist(&hist[j]); } cvDestroyWindow("Original"); return 0; }
CvHistogram结构typedef struct CvHistogram { int type; CvArr* bins; float thresh[CV_MAX_DIM][2]; /* for uniform histograms */ float** thresh2; /* for non-uniform histograms */ CvMatND mat; /* embedded matrix header for array histograms */ } CvHistogram;
bins :用于存放直方图每个灰度级数目的数组指针,数组在cvCreateHist的时候创建,其维数由cvCreateHist确定(一般以一维比较常见)
CreateHist
CvHistogram* cvCreateHist( int dims, int* sizes, int type,float** ranges=NULL, int uniform=1 );
-
dims
- 直方图维数的数目 sizes
- 直方图维数尺寸的数组 type
-
直方图的表示格式
:
CV_HIST_ARRAY
意味着直方图数据表示为多维密集数组 CvMatND;CV_HIST_TREE
意味着直方图数据表示为多维稀疏数组 CvSparseMat.
ranges
-
图中方块范围的数组
.它的内容取决于参数
uniform
的值。这个范围的用处是确定何时计算直方图或决定反向映射( backprojected),每个方块对应于输入图像的哪个 /哪组值。
uniform
-
归一化标识。
如果不为
0,则
ranges[i]
(0<=i<cDims
,译者注:cDims
为直方图的维数,对于灰度图为 1,彩色图为 3)是包含两个元素的范围数组,包括直方图第i
维的上界和下界。在第i
维上的整个区域 [lower,upper]被分割成dims[i]
个相等的块(译者注:dims[i]
表示直方图第 i维的块数),这些块用来确定输入象素的第i
个值(译者注:对于彩色图像,i
确定 R,G,或者 B)的对应的块;如果为 0,则ranges[i]
是包含dims[i]+1
个元素的范围数组,包括lower
0
,upper
0
,lower
1
,upper
1
==lower
2
,..., upper
dims[i]-1
,其中lower
j
和upper
j
分别是直方图第i
维上第j
个方块的上下界(针对输入象素的第i
个值)。任何情况下,输入值如果超出了一个直方块所指定的范围外,都不会被 cvCalcHist 计数,而且会被函数 cvCalcBackProject 置零。
函数 cvCreateHist 创建一个指定尺寸的直方图,并且返回创建的直方图的指针。如果数组的 ranges
是0,则直方块的范围必须由函数cvSetHistBinRanges 稍后指定。虽然 cvCalcHist 和 cvCalcBackProject 可以处理8-比特图像而无需设置任何直方块的范围,但它们都被假设等分0..255之间的空间。
CalcHist
计算图像image(s)的直方图
void cvCalcHist( IplImage** image, CvHistogram* hist, int accumulate=0, const CvArr* mask=NULL );
-
image
- 输入图像 s(虽然也可以使用 CvMat**). hist
- 直方图指针 accumulate
- 累计标识。如果设置,则直方图在开始时不被清零。这个特征保证可以为多个图像计算一个单独的直方图,或者在线更新直方图。 mask
- 操作 mask,确定输入图像的哪个象素被计数
函数 cvCalcHist 计算单通道或多通道图像的直方图。用来增加直方块的数组元素可从相应输入图像的同样位置提取。
CalcHist
计算图像image(s)的直方图
void cvCalcHist( IplImage** image, CvHistogram* hist, int accumulate=0, const CvArr* mask=NULL );
-
image
- 输入图像 s(虽然也可以使用 CvMat**). hist
- 直方图指针 accumulate
- 累计标识。如果设置,则直方图在开始时不被清零。这个特征保证可以为多个图像计算一个单独的直方图,或者在线更新直方图。 mask
- 操作 mask,确定输入图像的哪个象素被计数
函数 cvCalcHist 计算单通道或多通道图像的直方图。用来增加直方块的数组元素可从相应输入图像的同样位置提取。
GetMinMaxHistValue
发现最大和最小直方块
void cvGetMinMaxHistValue( const CvHistogram* hist, float* min_value, float* max_value, int* min_idx=NULL, int* max_idx=NULL );
-
hist
- 直方图 min_value
- 直方图最小值的指针 max_value
- 直方图最大值的指针 min_idx
- 数组中最小坐标的指针 max_idx
- 数组中最大坐标的指针
函数 cvGetMinMaxHistValue 发现最大和最小直方块以及它们的位置。任何输出变量都是可选的。在具有同样值几个极值中,返回具有最小下标索引(以字母排列顺序定)的那一个。
http://blog.csdn.net/lansatiankongxxc/article/details/8272633