直方图比较是对输入的两张图像进行计算得到直方图H1与H2,归一化到相同的尺度空间,然后可以通过计算H1与H2的之间的距离得到两个直方图的相似程度(每张图像都有唯一的直方图与之对应),进而比较图像本身的相似程度。Opencv提供的比较方法有四种:
Correlation 相关性比较
Chi-Square 卡方比较
Intersection 十字交叉性
Bhattacharyya distance 巴氏距离。
(1)直方图比较方法-相关性计算(CV_COMP_CORREL)
其中:
其中N是直方图的BIN个数,
是均值。
---------------------------------------------------------------------------------------------------------------------------------
(2)直方图比较方法-相关性计算(CV_COMP_CORREL)
H1,H2分别表示两个图像的直方图数据
---------------------------------------------------------------------------------------------------------------------------------
H1,H2分别表示两个图像的直方图数据
--------------------------------------------------------------------------------------------------------------------------------
(4)直方图比较方法-巴氏距离计算(CV_COMP_BHATTACHARYYA )
H1,H2分别表示两个图像的直方图数据,
---------------------------------------------------------------------------------------------------------------------------------
直方图比较API函数接口
- #API接口
- double compareHist(InputArray h1,InputArray H2,int method)
- //参数说明:
- 第一个参数InputArray类型 h1,直方图数据
- 第二个参数InputArray类型 h2,直方图数据
- 第三个参数int类型 method比较方法,上述四种方法之一
-
- 返回值:采用上述四中方法之一计算后的两个直方图相关系数
关于 int method 的取值:
- enum HistCompMethods {
- HISTCMP_CORREL = 0, //相关性比较
- HISTCMP_CHISQR = 1, //卡方比较
- HISTCMP_INTERSECT = 2, //十字交叉性
- HISTCMP_BHATTACHARYYA = 3, //巴氏距离
- HISTCMP_HELLINGER = HISTCMP_BHATTACHARYYA,
- HISTCMP_CHISQR_ALT = 4, //替代卡方:通常用于纹理比较。
- HISTCMP_KL_DIV = 5 //KL散度
- };
不同直方图相关性比较方法的特点:
- Correlation相关性比较(CV_COMP_CORREL)值越大,相关度越高,最大值为1,最小值为0,越接近1越相似
- Chi-Square卡方比较(CV_COMP_CHISQR) 值越小,相关度越高,最大值无上界,最小值0,越接近0越相似
- Intersection十字交叉性(CV_COMP_INTERSECT)对于相似度比较,值越大,表明相关度越高,最大值无上界;完美匹配为1,完全不匹配为0;
- Bhattacharyya distance巴氏距离(CV_COMP_BHATTACHARYYA)值越小,相关度越高,最大值为1,最小值为0,越接近1越相似
=========================================================================
- #include"stdafx.h"
- #include <opencv2/opencv.hpp>
- #include <iostream>
- #include <math.h>
-
- using namespace std;
- using namespace cv;
-
- string convertToString(double d);
- int main(int argc, char** argv) {
- Mat base, test1, test2; //RGB图像
- Mat hsvbase, hsvtest1, hsvtest2; //HSV图像
- base = imread("F:/photo/zx.jpg");
- if (!base.data) {
- printf("could not load image...\n");
- return -1;
- }
- test1 = imread("F:/photo/a.jpg");
- test2 = imread("F:/photo/c.jpg");
- //转化为HSV图像
- cvtColor(base, hsvbase, COLOR_BGR2HSV);
- cvtColor(test1, hsvtest1, COLOR_BGR2HSV);
- cvtColor(test2, hsvtest2, COLOR_BGR2HSV);
-
- int h_bins = 50; int s_bins = 60;
- int histSize[] = { h_bins, s_bins };
- // hue varies from 0 to 179, saturation from 0 to 255
- float h_ranges[] = { 0, 180 };
- float s_ranges[] = { 0, 256 };
- const float* ranges[] = { h_ranges, s_ranges };
- // Use the o-th and 1-st channels
- int channels[] = { 0, 1 };
- MatND hist_base;
- MatND hist_test1;
- MatND hist_test2;
-
- calcHist(&hsvbase, 1, channels, Mat(), hist_base, 2, histSize, ranges, true, false);
- normalize(hist_base, hist_base, 0, 1, NORM_MINMAX, -1, Mat());
-
- calcHist(&hsvtest1, 1, channels, Mat(), hist_test1, 2, histSize, ranges, true, false);
- normalize(hist_test1, hist_test1, 0, 1, NORM_MINMAX, -1, Mat());
-
- calcHist(&hsvtest2, 1, channels, Mat(), hist_test2, 2, histSize, ranges, true, false);
- normalize(hist_test2, hist_test2, 0, 1, NORM_MINMAX, -1, Mat());
-
- double basebase = compareHist(hist_base, hist_base, 2);//zx
- double basetest1 = compareHist(hist_base, hist_test1,2);//zx and a
- double basetest2 = compareHist(hist_base, hist_test2, 2);//zx and c
- double tes1test2 = compareHist(hist_test1, hist_test2, 2);//a and c
- printf("test1 compare with test2 correlation value :%f", tes1test2);
-
- Mat test12;
- test2.copyTo(test12);
- putText(base, convertToString(basebase), Point(50, 50), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 2, LINE_AA); //zx
- putText(test1, convertToString(basetest1), Point(50, 50), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 2, LINE_AA);//zx and a
- putText(test2, convertToString(basetest2), Point(50, 50), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 2, LINE_AA);//zx and c
- putText(test12, convertToString(tes1test2), Point(50, 50), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 2, LINE_AA);//a and c
-
- namedWindow("base", 0);
- resizeWindow("base", base.cols / 2, base.rows / 2);
- namedWindow("test1", 0);
- resizeWindow("test1", test1.cols / 2, test1.rows / 2);
- namedWindow("test2", 0);
- resizeWindow("test2", test2.cols / 2, test2.rows / 2);
-
- imshow("base", base);
- imshow("test1", test1);
- imshow("test2", test2);
- imshow("test12", test12);
-
- waitKey(0);
- return 0;
- }
-
- string convertToString(double d) {
- ostringstream os;
- if (os << d)
- return os.str();
- return "invalid conversion";
- }
---------------------------------------------------------------------------------------------------------------------------------
代码中,车道线图片base自行十字交叉性比较,basebase = 36.8538,数值越大,图像相关性程度越高 
base图片与test1图片进行十字交叉性比较,test1base = 9.55181,数值较小,图像相识度较低

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