OpenCV编程->对比直方图

OpenCv提供了5种对比直方图的方式:CORREL(相关)、CHISQR(卡方)、INTERSECT(相交)、BHATTACHARYYA、EMD(最小工作距离),其中CHISQR速度最快,EMD速度最慢且有诸多限制,但是EMD的效果可能最好。

接下来开始测试一下:

对比函数如下:

#define cvQueryHistValue_3D( hist, idx0, idx1, idx2 )      cvGetReal3D( (hist)->bins, (idx0), (idx1), (idx2) )
//画直方图用
int HistogramBins = 256;
float HistogramRange1[2]={0,255};
float *HistogramRange[1]={&HistogramRange1[0]};

void histemd(IplImage* src,IplImage* src1)
{
   IplImage* hsv = cvCreateImage( cvGetSize(src), 8, 3 );
   IplImage* hsv1 = cvCreateImage( cvGetSize(src), 8, 3 );
   cvCvtColor( src, hsv, CV_BGR2HSV );
   cvCvtColor( src1, hsv1, CV_BGR2HSV );
   IplImage* h_plane = cvCreateImage( cvGetSize(src), 8, 1 );
   IplImage* s_plane = cvCreateImage( cvGetSize(src), 8, 1 );
   IplImage* v_plane = cvCreateImage( cvGetSize(src), 8, 1 );
   IplImage* h_plane1 = cvCreateImage( cvGetSize(src), 8, 1 );
   IplImage* s_plane1 = cvCreateImage( cvGetSize(src), 8, 1 );
   IplImage* v_plane1 = cvCreateImage( cvGetSize(src), 8, 1 );
   IplImage* planes[] = { h_plane, s_plane,v_plane };
   IplImage* planes1[] = { h_plane1, s_plane1,v_plane1 };
    cvSplit( hsv, h_plane, s_plane, v_plane, 0 );
    cvSplit( hsv1, h_plane1, s_plane1, v_plane1, 0 );
   // Build the histogram and compute its contents.
   //计算规模与h_bins*s_bins*v_bins成指数关系,原先 int h_bins = 32, s_bins = 30, v_bins = 8 时,运行半天都没反应
   int h_bins = 8, s_bins = 5, v_bins = 5;
    CvHistogram* hist, *hist1;
   {
      int hist_size[] = { h_bins, s_bins ,v_bins};
      float h_ranges[] = { 0, 180 }; // hue is [0,180]
      float s_ranges[] = { 0, 255 };
      float v_ranges[] = { 0, 255 };
      float* ranges[] = { h_ranges, s_ranges ,v_ranges};
      hist = cvCreateHist(
         3,
         hist_size,
         CV_HIST_ARRAY,
         ranges,
         1
         );
      hist1 = cvCreateHist(
         3,
         hist_size,
         CV_HIST_ARRAY,
         ranges,
         1
         );
   }
   cvCalcHist( planes, hist, 0, 0 ); //Compute histogram
   cvNormalizeHist( hist, 1.0 ); //Normalize it
   cvCalcHist( planes1, hist1, 0, 0 ); //Compute histogram
   cvNormalizeHist( hist1, 1.0 ); //Normalize it  

   CvMat* sig1,*sig2;
   int numrows = h_bins*s_bins*v_bins;  

   sig1 = cvCreateMat(numrows, 4, CV_32FC1);
   sig2 = cvCreateMat(numrows, 4, CV_32FC1);
   int h,s,v;
   for( h = 0; h < h_bins; h++ )
   {
      for( s = 0; s < s_bins; s++ )
      {
         for( v=0; v < v_bins; v++)
         {
            float bin_val = cvQueryHistValue_3D( hist, h, s,v );  

            cvSet2D(sig1,h*s_bins*v_bins + s*v_bins+v,0,cvScalar(bin_val)); //bin value
            cvSet2D(sig1,h*s_bins*v_bins + s*v_bins+v,1,cvScalar(h)); //Coord 1
            cvSet2D(sig1,h*s_bins*v_bins + s*v_bins+v,2,cvScalar(s)); //Coord 2
            cvSet2D(sig1,h*s_bins*v_bins + s*v_bins+v,3,cvScalar(v)); //Coord 3  

            bin_val = cvQueryHistValue_3D( hist1, h, s,v );
            cvSet2D(sig2,h*s_bins*v_bins + s*v_bins+v,0,cvScalar(bin_val)); //bin value
            cvSet2D(sig2,h*s_bins*v_bins + s*v_bins+v,1,cvScalar(h)); //Coord 1
            cvSet2D(sig2,h*s_bins*v_bins + s*v_bins+v,2,cvScalar(s)); //Coord 2
            cvSet2D(sig2,h*s_bins*v_bins + s*v_bins+v,3,cvScalar(v)); //Coord 3  

         }
      }
   }  

   float emd = cvCalcEMD2(sig1,sig2,CV_DIST_L2);
   printf("CV_COMP_EMD :%3.1f%%",(1-emd)*100);  

   cvNamedWindow( "Source1", 1 );
   cvMoveWindow("Source1", 0, 0);
   cvShowImage( "Source1", src );
   cvNamedWindow( "Source2", 1 );
   cvMoveWindow("Source2", 550, 0);
   cvShowImage( "Source2", src1 );
   cvWaitKey(0);
}

void CompareHist(const char* imagefile1, const char* imagefile2)
{
    IplImage *image1=cvLoadImage(imagefile1, 0);
    IplImage *image2=cvLoadImage(imagefile2, 0);

	IplImage *image3=cvLoadImage(imagefile1,1);
    IplImage *image4=cvLoadImage(imagefile2,1);

    CvHistogram *Histogram1 = cvCreateHist(1, &HistogramBins, CV_HIST_ARRAY,HistogramRange);
    CvHistogram *Histogram2 = cvCreateHist(1, &HistogramBins, CV_HIST_ARRAY,HistogramRange);

    cvCalcHist(&image1, Histogram1);
    cvCalcHist(&image2, Histogram2);

    cvNormalizeHist(Histogram1, 1);
    cvNormalizeHist(Histogram2, 1);

    // CV_COMP_CHISQR,CV_COMP_BHATTACHARYYA这两种都可以用来做直方图的比较,值越小,说明图形越相似
    printf("CV_COMP_CHISQR : %.4f\n", cvCompareHist(Histogram1, Histogram2, CV_COMP_CHISQR));//卡方
    printf("CV_COMP_BHATTACHARYYA : %.4f\n", cvCompareHist(Histogram1, Histogram2, CV_COMP_BHATTACHARYYA));

    // CV_COMP_CORREL, CV_COMP_INTERSECT这两种直方图的比较,值越大,说明图形越相似
    printf("CV_COMP_CORREL : %.4f\n", cvCompareHist(Histogram1, Histogram2, CV_COMP_CORREL));//相关
    printf("CV_COMP_INTERSECT : %.4f\n", cvCompareHist(Histogram1, Histogram2, CV_COMP_INTERSECT));//相交
	 histemd(image3,image4);

}

在主函数里面调用:

 CompareHist("1001.png", "1002.png");

得到如下测试结果:

对于不同图片:

对于做直方图对比,对比图像的颜色背景需要一致,不然就出入很大。

参考:

http://www.cnblogs.com/slysky/archive/2011/10/13/2210745.html

http://blog.csdn.net/nicebooks/article/details/8175002

OpenCV编程->对比直方图,布布扣,bubuko.com

时间: 2024-10-05 16:50:31

OpenCV编程->对比直方图的相关文章

OpenCV编程-&gt;RGB直方图统计

我们在处理彩色图像时,特别是在做局部图像的阈值分割时,需要一个直观的RGB统计图. 接下来开始实现. 代码: void CalcHistRGB() { IplImage* img_source; if (img_source = cvLoadImage("101.jpg",1)) { IplImage* RedChannel = cvCreateImage( cvGetSize(img_source), 8, 1); IplImage* GreenChannel = cvCreateI

《OpenCV:直方图应用:直方图均衡化,直方图匹配,对比直方图》

直方图均衡化 直方图均衡化(Histogram Equalization)是直方图最典型的应用,是图像点运算的一种.对于一幅输入图像,通过运算产生一幅输出图像,点运算是指输出图像的每个像素点的灰度值由输入像素点决定,即: 直方图均衡化是通过灰度变换将一幅图像转换为另一幅具有均衡直方图,即在每个灰度级上都具有相同的象素点数过程.从分布图上的理解就是希望原始图像中y轴的值在新的分布中尽可能的展开.变换过程是利用累积分布函数对原始分布进行映射,生成新的均匀拉伸的分布.因此对应每个点的操作是寻找原始分布

iOS并发编程对比总结,NSThread,NSOperation,GCD - iOS

1. 多线程概念 进程 正在进行中的程序被称为进程,负责程序运行的内存分配 每一个进程都有自己独立的虚拟内存空间 线程 线程是进程中一个独立的执行路径(控制单元) 一个进程中至少包含一条线程,即主线程 可以将耗时的执行路径(如:网络请求)放在其他线程中执行 创建线程的目的就是为了开启一条新的执行路径,运行指定的代码,与主线程中的代码实现同时运行 1.1 多任务系统调度示意图 说明:每个应用程序由操作系统分配的短暂的时间片(Timeslice)轮流使用CPU,由于CPU对每个时间片的处理速度非常快

OpenCV编程-&gt;Windows7下调用iPhnoe摄像头

//////////////////////////////////////////////////////////////  指尖热度原创,转载请注明来自http://blog.csdn.net/sunboyiris  ///////////////////////////////////////////////////// 首先在iPhone上装webcamera软件,Windows7系统上安装webcamera软件. 在Windows7系统上的webcamera上设置如下: 点击进入设置如

OPENCV(5) &mdash;&mdash; 图像直方图

新版本对直方图不再使用之前的histogram的形式,而是用统一的Mat或者MatND的格式来存储直方图,可见新版本Mat数据结构的优势. C++: void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, OutputArray hist, intdims, const int* histSize, const float** ranges, bool uniform=true, bo

根据MATLAB的histeq函数改写的运行在OpenCV下的直方图规定化C源码!

据说,图像的直方图规定化比直方图均衡化用得更多,但是很奇怪的是OpenCV居然没有图像直方图规定化的源码!所以,我就有必要在OpenCV下写一个图像直方图规定化处理的函数,以方便将来使用. 我在网上找了几个直方图均稀化的源码,并基于OpenCV来改写这些源码,效果都不如MATLAB的histeq函数,这其中改写的艰辛与繁琐就不细说了.最后,没办法,只好学习MATALB的histeq函数源码,并对其进行基于OpenCV的改写. 虽然我最终改写成功了,但是对算法还是不太理解,只能按照MATLAB的帮

OpenCv 020---图像直方图反向投影

1 前备知识 直方图的方向投影原理及代码实现 反向投影的直观理解 直方图反向投影的作用 2 所用到的主要OpenCv API /** @brief 计算(一个或多个)数组的直方图 */ void calcHist( const Mat* images, int nimages, const int* channels, InputArray mask, OutputArray hist, int dims, const int* histSize, const float** ranges, b

OpenCV编程-&amp;gt;Windows7下调用iPhnoe摄像头

//////////////////////////////////////////////////////////////  指尖热度原创,转载请注明来自http://blog.csdn.net/sunboyiris  ///////////////////////////////////////////////////// 首先在iPhone上装webcamera软件,Windows7系统上安装webcamera软件. 在Windows7系统上的webcamera上设置例如以下: 点击进入设

OpenCv编程

(1)用OpenCv加载.显示.保存图片: //加载图片 IplImage* m_img;//定义IplImage格式的图片头指针: m_img=cvLoadImage(m_imgLoc);//装载m_imgLoc路径处(如“E:\\1.jpg”)的图片: //显示图片 CDC* pDC=m_ctrlImgOld.GetDC(); HDC hDC=pDC->GetSafeHdc(); CRect rect; m_ctrlImgOld.GetClientRect(&rect); CvvImag