• OpenCV图像处理学习二十一,直方图比较方法


    一.直方图比较

    直方图比较是对输入的两张图像进行计算得到直方图H1与H2,归一化到相同的尺度空间,然后可以通过计算H1与H2的之间的距离得到两个直方图的相似程度(每张图像都有唯一的直方图与之对应),进而比较图像本身的相似程度。Opencv提供的比较方法有四种:

    Correlation 相关性比较

    Chi-Square 卡方比较

    Intersection 十字交叉性

    Bhattacharyya distance 巴氏距离。

    (1)直方图比较方法-相关性计算(CV_COMP_CORREL)

                 d(h1,h2)=I(H1(I)H¯1)(H2(I)H¯2)I(H1(I)H¯1)2I(H2(I)H2¯)2" role="presentation" style="position: relative;">d(h1,h2)=I(H1(I)H¯1)(H2(I)H¯2)I(H1(I)H¯1)2I(H2(I)H2¯)2

    其中:                     \bar{H}_{k} = \frac{1}{N}\sum_{j}^{}H_{k}\left ( J \right )  

    其中N是直方图的BIN个数,\bar{H}是均值。

    ---------------------------------------------------------------------------------------------------------------------------------

    (2)直方图比较方法-相关性计算(CV_COMP_CORREL)

                 d(h1,h2)=I(H1(I)H¯2)2H1(I)" role="presentation" style="position: relative;">d(h1,h2)=I(H1(I)H¯2)2H1(I)

    H1,H2分别表示两个图像的直方图数据

    ---------------------------------------------------------------------------------------------------------------------------------

    (3)直方图比较方法-十字交叉性计算(CV_COMP_INTERSECT)

                d(h1,h2)=Imin(H1(I),H2(I))" role="presentation" style="position: relative;">d(h1,h2)=Imin(H1(I),H2(I))

    H1,H2分别表示两个图像的直方图数据

    --------------------------------------------------------------------------------------------------------------------------------

    (4)直方图比较方法-巴氏距离计算(CV_COMP_BHATTACHARYYA )

             d(h1,h2)=11H¯1H¯2N2jH1(I)H2(I)" role="presentation" style="position: relative;">d(h1,h2)=11H¯1H¯2N2jH1(I)H2(I)

    H1,H2分别表示两个图像的直方图数据,

    ---------------------------------------------------------------------------------------------------------------------------------

    二.图像直方图比较方法

    • 加载原图像
    • 将图像色彩空间由BGR三通道转换为HSV空间(由于直方图对亮度和灰度比较敏感,色彩空间转换就是突出这两个因素尽量去除其他因素)
    • 计算直方图进行归一化处理,归一化到0到1之间,调用calcHistnormalize
    • 直方图比较,使用上述四种方法之一,调用compareHist

    直方图比较API函数接口

    1. #API接口
    2. double compareHist(InputArray h1,InputArray H2,int method)
    3. //参数说明:
    4. 第一个参数InputArray类型 h1,直方图数据
    5. 第二个参数InputArray类型 h2,直方图数据
    6. 第三个参数int类型 method比较方法,上述四种方法之一
    7. 返回值:采用上述四中方法之一计算后的两个直方图相关系数

    关于 int method 的取值:

    1. enum HistCompMethods {
    2. HISTCMP_CORREL = 0, //相关性比较
    3. HISTCMP_CHISQR = 1, //卡方比较
    4. HISTCMP_INTERSECT = 2, //十字交叉性
    5. HISTCMP_BHATTACHARYYA = 3, //巴氏距离
    6. HISTCMP_HELLINGER = HISTCMP_BHATTACHARYYA,
    7. HISTCMP_CHISQR_ALT = 4, //替代卡方:通常用于纹理比较。
    8. HISTCMP_KL_DIV = 5 //KL散度
    9. };

    不同直方图相关性比较方法的特点:

    1. Correlation相关性比较(CV_COMP_CORREL)值越大,相关度越高,最大值为1,最小值为0,越接近1越相似
    2. Chi-Square卡方比较(CV_COMP_CHISQR) 值越小,相关度越高,最大值无上界,最小值0,越接近0越相似
    3. Intersection十字交叉性(CV_COMP_INTERSECT)对于相似度比较,值越大,表明相关度越高,最大值无上界;完美匹配为1,完全不匹配为0
    4. Bhattacharyya distance巴氏距离(CV_COMP_BHATTACHARYYA)值越小,相关度越高,最大值为1,最小值为0,越接近1越相似

    =========================================================================

    代码实现

    1. #include"stdafx.h"
    2. #include <opencv2/opencv.hpp>
    3. #include <iostream>
    4. #include <math.h>
    5. using namespace std;
    6. using namespace cv;
    7. string convertToString(double d);
    8. int main(int argc, char** argv) {
    9. Mat base, test1, test2; //RGB图像
    10. Mat hsvbase, hsvtest1, hsvtest2; //HSV图像
    11. base = imread("F:/photo/zx.jpg");
    12. if (!base.data) {
    13. printf("could not load image...\n");
    14. return -1;
    15. }
    16. test1 = imread("F:/photo/a.jpg");
    17. test2 = imread("F:/photo/c.jpg");
    18. //转化为HSV图像
    19. cvtColor(base, hsvbase, COLOR_BGR2HSV);
    20. cvtColor(test1, hsvtest1, COLOR_BGR2HSV);
    21. cvtColor(test2, hsvtest2, COLOR_BGR2HSV);
    22. int h_bins = 50; int s_bins = 60;
    23. int histSize[] = { h_bins, s_bins };
    24. // hue varies from 0 to 179, saturation from 0 to 255
    25. float h_ranges[] = { 0, 180 };
    26. float s_ranges[] = { 0, 256 };
    27. const float* ranges[] = { h_ranges, s_ranges };
    28. // Use the o-th and 1-st channels
    29. int channels[] = { 0, 1 };
    30. MatND hist_base;
    31. MatND hist_test1;
    32. MatND hist_test2;
    33. calcHist(&hsvbase, 1, channels, Mat(), hist_base, 2, histSize, ranges, true, false);
    34. normalize(hist_base, hist_base, 0, 1, NORM_MINMAX, -1, Mat());
    35. calcHist(&hsvtest1, 1, channels, Mat(), hist_test1, 2, histSize, ranges, true, false);
    36. normalize(hist_test1, hist_test1, 0, 1, NORM_MINMAX, -1, Mat());
    37. calcHist(&hsvtest2, 1, channels, Mat(), hist_test2, 2, histSize, ranges, true, false);
    38. normalize(hist_test2, hist_test2, 0, 1, NORM_MINMAX, -1, Mat());
    39. double basebase = compareHist(hist_base, hist_base, 2);//zx
    40. double basetest1 = compareHist(hist_base, hist_test1,2);//zx and a
    41. double basetest2 = compareHist(hist_base, hist_test2, 2);//zx and c
    42. double tes1test2 = compareHist(hist_test1, hist_test2, 2);//a and c
    43. printf("test1 compare with test2 correlation value :%f", tes1test2);
    44. Mat test12;
    45. test2.copyTo(test12);
    46. putText(base, convertToString(basebase), Point(50, 50), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 2, LINE_AA); //zx
    47. putText(test1, convertToString(basetest1), Point(50, 50), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 2, LINE_AA);//zx and a
    48. putText(test2, convertToString(basetest2), Point(50, 50), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 2, LINE_AA);//zx and c
    49. putText(test12, convertToString(tes1test2), Point(50, 50), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 2, LINE_AA);//a and c
    50. namedWindow("base", 0);
    51. resizeWindow("base", base.cols / 2, base.rows / 2);
    52. namedWindow("test1", 0);
    53. resizeWindow("test1", test1.cols / 2, test1.rows / 2);
    54. namedWindow("test2", 0);
    55. resizeWindow("test2", test2.cols / 2, test2.rows / 2);
    56. imshow("base", base);
    57. imshow("test1", test1);
    58. imshow("test2", test2);
    59. imshow("test12", test12);
    60. waitKey(0);
    61. return 0;
    62. }
    63. string convertToString(double d) {
    64. ostringstream os;
    65. if (os << d)
    66. return os.str();
    67. return "invalid conversion";
    68. }

    ---------------------------------------------------------------------------------------------------------------------------------

    图像处理效果

    代码中,车道线图片base自行十字交叉性比较,basebase = 36.8538,数值越大,图像相关性程度越高 

    base图片与test1图片进行十字交叉性比较,test1base = 9.55181,数值较小,图像相识度较低

    下面图像是test1图像与test2图像直方图对比,test2base = 7.98399,相识度较小

  • 相关阅读:
    【 第十六章 Lambda表达式】
    windows中nginx配置负载均衡
    Mybatis mapper报错:Class not found: org.jboss.vfs.VFS
    算法通过村第十三关-术数|青铜笔记|数字与数学
    电脑系统重装后音频驱动程序怎么修复
    Java:代理模式详解
    多种方式计算当天与另一天的间隔天数 Java实现
    数据库——DML:增删改
    部署vue element-ui admin报错(vue2)
    网络安全——HTTP头部注入
  • 原文地址:https://blog.csdn.net/weixin_44651073/article/details/126671677