直方图比较方法-概述
对输入的两张图像计算得到直方图H1与H2,归一化到相同的尺度空间。然后可以通过计算H1与H2的之间的距离得到两个直方图的相似程度进而比较图像本身的相似程度。Opencv提供的比较方法有四种:
-Correlation 相关性比较
-Chi-Square 卡方比较
-Intersection 十字交叉性
-Bhattacharyya distance 巴氏距离
直方图比较方法-相关性计算(CV_COMP_CORREL)
其中,
其中N是直方图的BIN个数,H-是均值
直方图比较方法-卡方计算(CV_COMP_CHISQR)
H1,H2分别表示两个图像的直方图数据。
直方图比较方法-十字计算(CV_COMP_INTERSECT)
H1,H2分别表示两个图像的直方图数据
直方图比较方法-巴氏距离计算(CV_COMP_BHATTACHARYYA )
H1,H2分别表示两个图像的直方图数据
相关API
l首先把图像从RGB色彩空间转换到HSV色彩空间cvtColor
l计算图像的直方图,然后归一化到[0~1]之间calcHist和normalize;
l使用上述四种比较方法之一进行比较compareHist
相关API cv::compareHist
compareHist(
InputArray h1, // 直方图数据,下同
InputArray H2,
int method// 比较方法,上述四种方法之一
)
演示代码
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
Mat base,test1,test2;
string convertToString(double d);
int main(int agrc, char** agrv) {
Mat hsvbase, hsvtest1, hsvtest2;
base = imread("C:/Users/liyangxian/Desktop/bjl/base.jpg");
if (!base.data) {
printf("no load..\n");
return -1;
}
test1 = imread("C:/Users/liyangxian/Desktop/bjl/test1.jpg");
test2 = imread("C:/Users/liyangxian/Desktop/bjl/test2.jpg");
//RGB to HSV
cvtColor(base, hsvbase, CV_RGB2HSV);
cvtColor(test1, hsvtest1, CV_RGB2HSV);
cvtColor(test2, hsvtest2, CV_RGB2HSV);
//计算直方图+归一化
int h_bins = 50; int s_bins = 60;
int histSize[] = { h_bins,s_bins };
float h_ranges[] = { 0,180 };
float s_ranges[] = { 0,256 };
const float * range[] = {h_ranges,s_ranges};
int channels[] = { 0,1 };
Mat hist_base, hist_test1, hist_test2;
calcHist(&hsvbase,1,channels, Mat(), hist_base, 2, histSize, range, true, false);
normalize(hist_base, hist_base, 0, 1, NORM_MINMAX, -1, Mat());
calcHist(&hsvtest1, 1, channels, Mat(), hist_test1, 2, histSize, range, true, false);
normalize(hist_test1, hist_test1, 0, 1, NORM_MINMAX, -1, Mat());
calcHist(&hsvtest2, 1, channels, Mat(), hist_test2, 2, histSize, range, true, false);
normalize(hist_test2, hist_test2, 0, 1, NORM_MINMAX, -1, Mat());
//直方图比较
double basebase = compareHist(hist_base, hist_base, CV_COMP_BHATTACHARYYA);
double basetest1 = compareHist(hist_base, hist_test1, CV_COMP_BHATTACHARYYA);
double basetest2 = compareHist(hist_base, hist_test2, CV_COMP_BHATTACHARYYA);
double test1test2 = compareHist(hist_test1, hist_test2, CV_COMP_BHATTACHARYYA);
printf("test1 compare with test2 correlation value:%f", test1test2);
Mat test12;
test2.copyTo(test12);
putText(base,convertToString(basebase),Point(50,50),CV_FONT_HERSHEY_COMPLEX,1,Scalar(0,0,255),2,LINE_AA);
putText(test1, convertToString(basetest1), Point(50, 50), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 2, LINE_AA);
putText(test2, convertToString(basetest2), Point(50, 50), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 2, LINE_AA);
putText(test12, convertToString(test1test2), Point(50, 50), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 2, LINE_AA);
namedWindow("base",CV_WINDOW_AUTOSIZE);
namedWindow("test1", CV_WINDOW_AUTOSIZE);
namedWindow("test2", CV_WINDOW_AUTOSIZE);
namedWindow("test12", CV_WINDOW_AUTOSIZE);
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";
}