【opencv学习笔记】026之直方图比较 - compareHist函数详解

1.前言

        想了解直方图比较中每种比较的方式,比较的原理,希望大家能有一定的概率论基础,或者统计学基础,如果对这块理论不太了解,还想深入学习算法,建议先学习一下概率论或统计学。

如果你想了解更多有关于计算机视觉、OpenCV、机器学习、深度学习等相关技术的内容,想与更多大佬一起沟通,那就扫描下方二维码加入我们吧!

2.直方图比较概述

        对输入的两张图像进行直方图均衡化及直方图计算步骤后,可以对两个图像的直方图进行对比,并通过对比的结果得到一些我们想要的结论。

3.直方图比较应用

(1)图像相似度比较

        如果我们有两张图像,并且这两张图像的直方图一样,或者有极高的相似度,那么在一定程度上,我们可以认为这两幅图是一样的,这就是直方图比较的应用之一。

(2)分析图像之间关系

        两张图像的直方图反映了该图像像素的分布情况,可以利用图像的直方图,来分析两张图像的关系。

4.直方图比较原理

        要比较两个直方图(H1 和 H2),首先必须要选择一个衡量直方图相似度的对比标准,我们设为d(H1,H2),

5.直方图比较方法

(1)相关性比较(Correlation)

        相关性比较公式如下:

 

        其中

        如果H1 = H2,即两个图的直方图一样,分子等于分母,值为1,所以在不严格的情况下,当值为1时,可以认为两个图是一样的。但是也有可能会出现两个图不一样,但是两个图的直方图是一样的情况。因为直方图计算的是像素点个数的分布情况,但是不会显示像素点的位置,所以有可能会出现两幅图片不一样,但是相同像素的个数完全一样,那他们的直方图也是一样的,不过这种情况,不常有。

        相关性比较公式来源于统计学中的相关系数,最早由统计学家卡尔·皮尔逊设计的统计指标,是研究变量之间线性相关程度的量,一般用字母 r 表示。

        其中,Cov(X,Y)为X与Y的协方差,Var[X]为X的方差,Var[Y]为Y的方差。如果想学算法,但是又觉得数学很枯燥的话,可以推荐大家一本书,据说很有趣,叫《漫画统计学》。当然,如果是做研究,还是养成不怕枯燥的好习惯。

        在那本书上讲到:相关系数适合数值与数值之间的关联性分析。这个公式里面比上面多了一点,是这个公式的取值范围

        下面是该公式更加详细的取值范围分析:并且如果两个变量的相关性越强,相关系数就会越接近±1,相关性越弱,相关系数越接近0。

        相关系数的值若为正值,称为正相关;相关系数的值若为负值,称为负相关;相关系数的值为0,称为不相关。

(2)Chi-Square(卡方比较)

        通过这个公式我们能够发现,卡方比较和相关性比较恰恰相反,相关性比较的值为0,相似度最低,越趋近于1,相似度越低;卡方比较则是,值为0时说明H1= H2,这个时候相似度最高。

        卡方比较来源于卡方检验,卡方检验就是统计样本的实际观测值与理论推断值之间的偏离程度,实际观测值与理论推断值之间的偏离程度就决定卡方值的大小,卡方值越大,越不符合;卡方值越小,偏差越小,越趋于符合,若两个值完全相等时,卡方值就为0,表明理论值完全符合。卡方检验的公式如下,其中fi是观测频率,npi是期望频率,X²是卡方值。

(3)Intersection(十字交叉性)

        这个就比较简单了,对比H1,H2并求出最小值,最后求和。

(4)Bhattacharyya distance(巴氏距离)

        在直方图相似度计算时,巴氏距离获得的效果最好,但计算是最为复杂的。巴氏距离的计算结果,其值完全匹配为1,完全不匹配则为0。

        在统计学中,巴氏距离(巴塔恰里雅距离 / Bhattacharyya distance)用于测量两离散概率分布。它常在分类中测量类之间的可分离性。在同一定义域X中,概率分布p和q的巴氏距离定义如下:离散概率分布;连续概率分布。

6.API介绍——compareHist

(1)步骤

        a.先用cvtColor()把图像从RGB色彩空间转换到HSV色彩空间;

        b.计算图像的直方图,然后归一化到[0~1]之间,用到函数 calcHist() 和 normalize() ;

        c.使用上述的四种方法之一进行比较,用到函数compareHist()。

(2)API介绍

        函数一共有三个参数,一个输入图像,一个输出图像,一个比较方法。比较方法的取值的情况为上面的四种方法,在OpenCV中,每个都有自己的名字:Correlation ( CV_COMP_CORREL );Chi-Square ( CV_COMP_CHISQR );Intersection ( CV_COMP_INTERSECT );Bhattacharyya 距离( CV_COMP_BHATTACHARYYA )。

7.效果展示

(1)步骤分解

a.加载图像

b.将图像从BGR空间转化为HSV空间

c.计算直方图并归一化处理

d.直方图比较

e.展示图像

(2)源码及效果

 
  1. #define INPUT_TITLE0 "input image src"

  2. #define INPUT_TITLE1 "input image srctest1"

  3. #define INPUT_TITLE2 "input image srctest2"

  4. #define OUTPUT_TITLE "name"

  5.  
  6. #include<iostream>

  7. #include<math.h>

  8. #include<opencv2\opencv.hpp>

  9.  
  10. using namespace std;

  11. using namespace cv;

  12.  
  13. string convertToString(double d);

  14.  
  15. int main() {

  16. // 加载图像

  17. Mat src, srctest1, srctest2;

  18. src = imread("D:/SunWuKong.jpg");

  19. srctest1 = imread("D:/SunWuKong1.jpg");

  20. srctest2 = imread("D:/GraySunWuKong.jpg");

  21.  
  22. if (!src.data|| !srctest1.data|| !srctest2.data)

  23. {

  24. cout << "ERROR : could not load image.";

  25. return -1;

  26. }

  27.  
  28. imshow("【src 原图】", src);

  29. imshow("【srctest1 原图】", srctest1);

  30. imshow("【srctest2 原图】", srctest2);

  31.  
  32. //从RGB色彩空间转化为HSV色彩空间

  33. cvtColor(src, src, CV_BGR2HSV);

  34. cvtColor(srctest1, srctest1, CV_BGR2HSV);

  35. cvtColor(srctest2, srctest2, CV_BGR2HSV);

  36.  
  37. //定义直方图计算所需要的各种参数

  38. int h_bins = 50;

  39. int s_bins = 60;

  40. int histSize[] = { h_bins,s_bins };

  41.  
  42. float h_ranges[] = { 0,180 };

  43. float s_ranges[] = { 0,256 };

  44. const float* ranges[] = { h_ranges, s_ranges };

  45.  
  46. int channels[] = { 0,1 };

  47.  
  48. //MatND 是 Mat的别名,方便区分经过直方图计算处理后和输入图像

  49. MatND hist_src;

  50. MatND hist_srctest1;

  51. MatND hist_srctest2;

  52.  
  53. //计算直方图并归一化处理

  54. calcHist(&src, 1, channels, Mat(), hist_src, 2, histSize, ranges, true, false);

  55. normalize(hist_src, hist_src, 0, 1, NORM_MINMAX, -1, Mat());

  56.  
  57. calcHist(&srctest1, 1, channels, Mat(), hist_srctest1, 2, histSize, ranges, true, false);

  58. normalize(hist_srctest1, hist_srctest1, 0, 1, NORM_MINMAX, -1, Mat());

  59.  
  60. calcHist(&srctest2, 1, channels, Mat(), hist_srctest2, 2, histSize, ranges, true, false);

  61. normalize(hist_srctest2, hist_srctest2, 0, 1, NORM_MINMAX, -1, Mat());

  62.  
  63. //直方图比较

  64. double src_src = compareHist(hist_src, hist_src, CV_COMP_CORREL);

  65. double src_srctest1 = compareHist(hist_src, hist_srctest1, CV_COMP_CORREL);

  66. double src_srctest2 = compareHist(hist_src, hist_srctest2, CV_COMP_CORREL);

  67. double srctest1_srctest2 = compareHist(hist_srctest1, hist_srctest2, CV_COMP_CORREL);

  68.  
  69. cout << "src compare with src correlation value : " << src_src << endl;

  70. cout << "src compare with srctest1 correlation value : " << src_srctest1 << endl;

  71. cout << "src compare with srctest2 correlation value : " << src_srctest2 << endl;

  72.  
  73. //给每个图像上添加文字,内容为该图片和原始图片的比较结果

  74. putText(src, convertToString(src_src), Point(50, 50), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(0, 255, 255), 2, LINE_AA);

  75. putText(srctest1, convertToString(src_srctest1), Point(50, 50), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 2, LINE_AA);

  76. putText(srctest2, convertToString(src_srctest2), Point(50, 50), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(255, 0, 255), 2, LINE_AA);

  77.  
  78. //图像的显示

  79. namedWindow(INPUT_TITLE0, CV_WINDOW_AUTOSIZE);

  80. namedWindow(INPUT_TITLE1, CV_WINDOW_AUTOSIZE);

  81. namedWindow(INPUT_TITLE2, CV_WINDOW_AUTOSIZE);

  82. //namedWindow(OUTPUT_TITLE, CV_WINDOW_AUTOSIZE);

  83.  
  84. imshow(INPUT_TITLE0, src);

  85. imshow(INPUT_TITLE1, srctest1);

  86. imshow(INPUT_TITLE2, srctest2);

  87.  
  88.  
  89. waitKey(0);

  90. return 0;

  91. }

  92.  
  93. string convertToString(double d) {

  94. ostringstream os;

  95. if (os<<d)

  96. {

  97. return os.str();

  98. }

  99. return "invalid conversion";

  100. }

【原图】

【相关性比较】

取值为[0,1],越接近1,直方图相似度越高。

【卡方比较】

取值大于0,越接近0,直方图相似度越高。

下面两种方式图像跟上面相同,只有数值不同,下面将得数分享给大家:

【十字交叉性】

src compare with src correlation value :           53.7653
src compare with srctest1 correlation value :   29.2811
src compare with srctest2 correlation value :   0.56726

【巴氏距离】

src compare with src correlation value :         0
src compare with srctest1 correlation value : 0.562044
src compare with srctest2 correlation value : 0.947251

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值