灰度直方图是灰度级的函数,描述的是图像中具有该灰度级的像素的个数:其横坐标是灰度级,纵坐标是该灰度出现的频率(像素的个数)。

在opencv中可以通过cvCreateHist()来生成直方图


CvHistogram* cvCreateHist(     int dims,            int* sizes,        int type,         float** ranges=NULL,      int uniform=1       )     dims        //直方图包含的维数     sizes      //数组的长度等于dims,数组中每个整数表示分配给对应维数的的bin的个数     type       //表示存储类型,CV_HIST_ARRAy表示用密集多维矩阵结构存储直方图,CV_HIST_SPARSE表示数据已稀疏矩阵方式存储     ranges=NULL,      //浮点数对的构成的数组,每个浮点数对表示对应维数的bin的区间的上下界     uniform=1       //非0表示均匀直方图,为NULL表示未知,即在后面可以设置。CvHistogram* cvCreateHist(

使用cvCalcHist()函数来计算直方图



void cvCalcHist(  IplImage** image,  CvHistogram* hist,  int accmulate=0,  const CvArr* mask=NULL  )  image  //是一个指向数组的IplImage*类型的指针,着允许利用多个图像通道  hist   //要计算的直方图  accmulate //非0时,表示直方图hist在读入图像之前没有被清零  mask //如果为非NULL,则只有与mask非零元素对应的像素点会被包含在计算直方图中。



1.单通道图像的直方图


#include "stdafx.h" #include <highgui.h> #include <math.h> #include <cv.h> int main() {  IplImage* sourceImage=0;    //以单通道读入图像  if(!(sourceImage=cvLoadImage("YAYA.jpg",0)))   return -1;   int hdims=51;      //分配给对应维数的bin的个数  float rangesArray[]={0,255};  float* ranges[]={rangesArray};  float maxValue;    CvHistogram* histogram=0;  histogram=cvCreateHist(1,&hdims,CV_HIST_ARRAY,ranges,1);    IplImage* histImage;      //用来显示直方图  histImage=cvCreateImage(cvGetSize(sourceImage),8,3);  cvZero(histImage);    //计算直方图  cvCalcHist(&sourceImage,histogram,0,0);    //获取最大值  cvGetMinMaxHistValue(histogram,0,&maxValue,0,0);    cvConvertScale(histogram->bins,histogram->bins,maxValue?255./maxValue:0,0);    float binsWidth;  binsWidth=histImage->width/hdims;  CvScalar color=CV_RGB(255,255,255);  for(int i=0;i<hdims;i++)  {   double value=(cvGetReal1D(histogram->bins,i)*histImage->height/255);   cvRectangle(histImage,cvPoint(i*binsWidth,histImage->height),cvPoint((i+1)*binsWidth,(int)(histImage->height-value)),color,1,8,0);  }  //显示   cvNamedWindow("sourceImage",0);  cvNamedWindow("histImage",0);  cvShowImage("sourceImage",sourceImage);  cvShowImage("histImage",histImage);  //释放资源  cvDestroyAllWindows();  cvReleaseImage(&sourceImage);  cvReleaseImage(&histImage);  cvReleaseHist(&histogram);   cvWaitKey(-1);   return 0; }

运行结果:


直方图与匹配_相似度


多通道图像的直方图

因为ccCalHist()只接受单通道图像,所以在调用cvCalcHist()之前,首先用cvSplit()将多通道图像分解为单通道图像。


#include "stdafx.h" #include <highgui.h> #include <math.h> #include <cv.h> int main() {     IplImage* sourceImage=0;     if(!(sourceImage=cvLoadImage("YAYA.jpg",1)))         return -1;      IplImage* hsvImage=cvCreateImage(cvGetSize(sourceImage),8,3);     cvCvtColor(sourceImage,hsvImage,CV_BGR2HSV);     IplImage* h_plane=cvCreateImage(cvGetSize(sourceImage),8,1);     IplImage* s_plane=cvCreateImage(cvGetSize(sourceImage),8,1);     IplImage* v_plane=cvCreateImage(cvGetSize(sourceImage),8,1);     cvSplit(hsvImage,h_plane,s_plane,v_plane,0);          int h_bins=30,s_bins=32;     CvHistogram* histogram;     {         int hist_size[]={h_bins,s_bins};         float h_ranges[]={0,180};         float s_ranges[]={0,255};         float* ranges[]={h_ranges,s_ranges};         histogram=cvCreateHist(             2,             hist_size,             CV_HIST_ARRAY,             ranges,             1             );     }     IplImage* planes[]={h_plane,s_plane};     cvCalcHist(planes,histogram,0,0);     cvNormalizeHist(histogram,1.0);     int scale=10;     IplImage* histImage=cvCreateImage(         cvSize(h_bins*scale,s_bins*scale),8,3);     cvZero(histImage);      float maxValue;     cvGetMinMaxHistValue(histogram,0,&maxValue,0,0);          for(int h=0;h<h_bins;h++)         for(int s=0;s<s_bins;s++)         {             float binValue=cvQueryHistValue_2D(histogram,h,s);             int intensity=cvRound(binValue*255./maxValue);             cvRectangle(                 histImage,                 cvPoint(h*scale,s*scale),                 cvPoint((h+1)*scale-1,(s+1)*scale-1),                 CV_RGB(intensity,intensity,intensity),                 CV_FILLED                 );         }          cvNamedWindow("hsvImage",1);         cvNamedWindow("histImage",1);          cvShowImage("hsvImage",hsvImage);         cvShowImage("histImage",histImage);         cvWaitKey(-1);         cvDestroyAllWindows();         cvReleaseImage(&sourceImage);         cvReleaseImage(&histImage);         cvReleaseHist(&histogram);         return 0; }

运行结果:

直方图与匹配_#include_02


直方图的相似度

计算直方图相似度的函数如下:


double cvCompareHist(  const CvHistogram* hist1,  const CvHistogram* hist2,  int method;           //距离标准 )

method的取值有:


CV_COMP_CORREL     完全匹配为1,完全不匹配为-1,数值越大越匹配

CV_COMP_CHISQR      低分比高分匹配的程度高,完全匹配的值为0,完全不匹配为无限值

CV_COMP_INTERSECT   高分表示好匹配,低分表示坏匹配

CV_COMP_BHATTACHARYYA     低分表示好匹配,高分表示换匹配。完全匹配为0,完全不匹配为0.



#include "stdafx.h" #include <highgui.h> #include <math.h> #include <cv.h> using namespace std; //对比两个直方图的相似度 int main() {     IplImage* templateImage=cvLoadImage("YAYA.jpg");     if(!templateImage)         return -1;     IplImage* grayImage=cvCreateImage(cvGetSize(templateImage),8,1);     cvCvtColor(templateImage,grayImage,CV_BGR2GRAY);     //首先加载图片,然后将图片变为灰度图          int hist_size=51;     float range[]={0,255};     float* ranges[]={range};      CvHistogram* histogram;     histogram=cvCreateHist(         1,         &hist_size,      //size  元素为对应bin的个数         CV_HIST_ARRAY,         ranges,         1         );     cvCalcHist(&grayImage,histogram,0,0);      IplImage* compareImage=cvLoadImage("YAYA2.jpg");     if(!compareImage)         return -1;     IplImage* compareGrayImage=cvCreateImage(cvGetSize(compareImage),8,1);     cvCvtColor(compareImage,compareGrayImage,CV_BGR2GRAY);     //首先加载图片,然后将图片变为灰度图          CvHistogram* compareHistogram;     compareHistogram=cvCreateHist(         1,         &hist_size,         CV_HIST_ARRAY,         ranges,         1         );     cvCalcHist(&compareGrayImage,compareHistogram,0,0);      //对直方图进行归一化操作     cvNormalizeHist(histogram,1);     cvNormalizeHist(compareHistogram,1);     //计算匹配系数     double degree=cvCompareHist(histogram,compareHistogram,         CV_COMP_CHISQR);     cout<<degree<<endl;     cvWaitKey(10000000);     cvDestroyAllWindows();     cvReleaseImage(&templateImage);     cvReleaseImage(&grayImage);     cvReleaseImage(&compareImage);     cvReleaseImage(&compareGrayImage);     cvReleaseHist(&compareHistogram);     cvReleaseHist(&histogram);     return 0; }


Reference

《学习opencv》