|
直方图比较方法-概述
对输入的两张图像计算得到直方图H1与H2,归一化到相同的尺度空间
然后可以通过计算H1与H2的之间的距离得到两个直方图的相似程度进
而比较图像本身的相似程度。Opencv提供的比较方法有四种:
Correlation 相关性比较
Chi-Square 卡方比较
Intersection 十字交叉性
Bhattacharyya distance 巴氏距离

直方图比较方法-相关性计算(CV_COMP_CORREL)
其中
其中N是直方图的BIN个数,

直方图比较方法-卡方计算(CV_COMP_CHISQR)
H1,H2分别表示两个图像的直方图数据

直方图比较方法-十字计算(CV_COMP_INTERSECT)
H1,H2分别表示两个图像的直方图数据

直方图比较方法-巴氏距离计算(CV_COMP_BHATTACHARYYA )
H1,H2分别表示两个图像的直方图数据

相关API
首先把图像从RGB色彩空间转换到HSV色彩空间cvtColor
计算图像的直方图,然后归一化到[0~1]之间calcHist和normalize;
使用上述四种比较方法之一进行比较compareHist

compareHist(
InputArray h1, // 直方图数据,下同
InputArray H2,
int method// 比较方法,上述四种方法之一
)

[C++] 纯文本查看 复制代码 /*
注意:
直方图比较方法-相关性计算(CV_COMP_CORREL)
数值越大越接近
直方图比较方法-卡方计算(CV_COMP_CHISQR)
数值越小越接近
直方图比较方法-十字计算(CV_COMP_INTERSECT)
结果混乱,避免使用
直方图比较方法-巴氏距离计算(CV_COMP_BHATTACHARYYA )
数值越小越接近
*/
#include <opencv2/opencv.hpp>
#include <iostream>
#include<math.h>
using namespace std;
using namespace cv;
//比较的方法:
//#define METHOD CV_COMP_CORREL
#define METHOD CV_COMP_CHISQR
//#define METHOD CV_COMP_INTERSECT
//#define METHOD CV_COMP_BHATTACHARYYA
Mat src,src1,src2, dst, gray;
string convertToString(double d);
int main(int argc, char** argv) {
src = imread("D:/IDE/opencv-3.1.0/demo.jpg");
src1 = imread("D:/IDE/opencv-3.1.0/demo.jpg");
src2 = imread("D:/IDE/opencv-3.1.0/demo2.jpg");
if (!src.data||!src2.data) {
printf("加载图片异常\n");
return -1;
}
//转换色彩空间RGB转到HSV
cvtColor(src, src, CV_BGR2HSV);
cvtColor(src1, src1, CV_BGR2HSV);
cvtColor(src2, src2, CV_BGR2HSV);
//计算直方图并归一化
int h_bins = 50;
int s_bins = 60;
int histSize[] = { h_bins,s_bins };
//取值范围
float h_rangs[] = { 0,180 };
float s_rangs[] = { 0,256 };
//修饰常量.不可改动
const float* rangs[] = { h_rangs,s_rangs };
//通道数
int channels[] = { 0,1 };
//定义多维类型
MatND hist_src;
MatND hist_src1;
MatND hist_src2;
//计算直方图
calcHist(&src, 1, channels, Mat(), hist_src, 2, histSize, rangs, true, false);
//归一化
normalize(hist_src,hist_src, 0, 1, NORM_MINMAX, -1, Mat());
calcHist(&src1, 1, channels, Mat(), hist_src1, 2, histSize, rangs, true, false);
normalize(hist_src1,hist_src1, 0, 1, NORM_MINMAX, -1, Mat());
calcHist(&src2, 1, channels, Mat(), hist_src2, 2, histSize, rangs, true, false);
normalize(hist_src2,hist_src2, 0, 1, NORM_MINMAX, -1, Mat());
//比较直方图,并返回值
double basesrc = compareHist(hist_src, hist_src, METHOD);
double basesrc1 = compareHist(hist_src, hist_src1, METHOD);
double basesrc2 = compareHist(hist_src, hist_src2, METHOD);
double result_src2 = compareHist(hist_src1, hist_src2, METHOD);
cout << "图1和图2的对比结果是:"<< result_src2 << endl;
putText(
src, convertToString(basesrc),
Point(50, 50),
CV_FONT_HERSHEY_COMPLEX,
1,
Scalar(0, 0, 255),
2,
LINE_AA
);
putText(
src1, convertToString(basesrc1),
Point(50, 50),
CV_FONT_HERSHEY_COMPLEX,
1,
Scalar(0, 0, 255),
2,
LINE_AA
);
putText(
src2, convertToString(basesrc2),
Point(50, 50),
CV_FONT_HERSHEY_COMPLEX,
1,
Scalar(0, 0, 255),
2,
LINE_AA
);
imshow("src", src);
imshow("src1", src1);
imshow("src2", src2);
waitKey(0);
return 0;
}
string convertToString(double d) {
ostringstream os;
if (os << d)
return os.str();
return "无效转换";
}
|
|