- 对输入的两张图像计算得到直方图H1,H2,归一化到相同的尺度空间然后可以通过计算H1和H2之间的距离得到两个直方图的相似程度,今儿比较两幅图像的相似程度。
- opencv 提供四种方法
- Correlation 相关性比较
- Chi-Square 卡方交叉性
- Intersection 十字交叉性
- Bhattacharyya distance 巴氏距离
一.直方图相关性计算 HISTCMP_CORREL
- d 的范围是(-1,1),越靠近1表示两个直方图越相似。N是BIN的个数。
二.卡方计算
HISTCMP_CHISQR
-
d越接近0,两个直方图越相似。
####三. 十字交叉判断相似
HISTCMP_INTERSECT -
取两个最小的直方图数据。不常用
四.巴氏距离
HISTCMP_BHATTACHARYYA
-d: 0-1. 越接近0越相关。很准确,直方图均值相比
####五.相关API及其方法
- 首先把图像从RGB色彩空间转换到HSV空间。直方图对H(色调),S(饱和度)较敏感,取这两个空间的直方图。
- 计算直方图 calcHist
- 将色彩空间归一化到 0-1: normalize()
- compareHist 使用上诉四种方法
compareHist{
直方图数据h1;
直方图数据h2;
int method; //比较方法之一
}
#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace cv;
using namespace std;
//double 转string
string convertToString(double d) {
ostringstream os;
if (os << d)
return os.str();
return "invalid conversion";
}
int main()
{
Mat hsv1, hsv2;
Mat src = imread("C:\\Users\\Administrator\\Pictures\\Saved Pictures\\timg6ZAGKYHR.jpg");
Mat src1 = imread("C:\\Users\\Administrator\\Pictures\\Saved Pictures\\timg9SXPUUP4.jpg");
MatND hist_base;//由于是多通道的矩阵用MatND
MatND hist_test1;
int channels[] = { 0,1 };//H,S通道
int h_bins = 50;
int s_bins = 60;
int histSize[] = { h_bins,s_bins };//BIN:50个阶层,,,60个阶层
float h_range[] = { 0 , 180 };//BIN:H(0-180),
float s_range[] = { 0,256 };//BIN:S(0-256),
const float* ranges[] = { h_range ,s_range };//注意此处是const
if (src.empty())
{
printf("ould not find image \n");
return -1;
}
cvtColor(src, hsv1, COLOR_BGR2HSV);
cvtColor(src1, hsv2, COLOR_BGR2HSV);
calcHist(&src, 1, channels, Mat(), hist_base, 2, histSize, ranges, true, false);
normalize(hist_base, hist_base, 0, 1, NORM_MINMAX, -1, Mat());
calcHist(&src1, 1, channels, Mat(), hist_test1, 2, histSize, ranges, true, false);
normalize(hist_test1, hist_test1, 0, 1, NORM_MINMAX, -1, Mat());
double src_src1 = compareHist(hist_base, hist_test1, HISTCMP_CORREL);//src1与src做直方图相关性比较
double src_src2 = compareHist(hist_base, hist_test1, HISTCMP_BHATTACHARYYA);//src1与src做直方图巴氏距离比较
putText(src, convertToString(src_src1), Point(50, 50), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 2, LINE_AA);
putText(src1, convertToString(src_src2), Point(50, 50), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 255, 255), 2, LINE_AA);
imshow("opencv set up demo", src);
imshow("opencv set up demo1", src1);
//直方图比较:两张图像或图像中的区域,若其直方图是相似的,其图像也可能是相似的。
waitKey(0);
return 1;
}