1、函数原型
// 原型一
double compareHist(InputArray H1,
InputArray H2,
int method)
// 原型二
double compareHist(const SparseMat &H1,
const SparseMat &H2,
int method)
2、函数功能
用指定的方法比较两个密集或两个稀疏直方图;
该函数适用于1-、2-、3维密集直方图,但不适用于高维稀疏直方图;在这种柱状图中,由于存在混叠和采样问题,非零柱状图的坐标会发生轻微的偏移;为了比较这些柱状图或更一般的加权点稀疏配置,考虑使用EMD函数;
3、参数详解
-
第一个参数,InputArray H1,待比较的第一个直方图;
-
第二个参数,InputArray H2,待比较的第二个直方图,与第一个直方图具有相同的大小;
-
第三个参数,int method,直方图比较的方法;
具体有如下方法:
(1) HISTCMP_CORREL,相关性;
相关性其中,
image.pngN是总的柱状图bins个数;
(2) HISTCMP_CHISQR ,卡方;
卡方(3) HISTCMP_INTERSECT,交叉;
交叉(4) HISTCMP_BHATTACHARYYA,Bhattacharyya距离(事实上,opencv计算了与Bhattacharyya系数相关的Hellinger距离);
Bhattacharyya距离(5) HISTCMP_HELLINGER,与HISTCMP_BHATTACHARYYA相同;
(6) HISTCMP_CHISQR_ALT,变种卡方,这种替代公式经常用于纹理比较;
(7) HISTCMP_KL_DIV,交叉熵的K-L散度;
交叉熵的K-L散度- 返回值,返回两个直方图比较的结果;
4、实验实例
#define INPUT_TITLE0 "input image srctest1-srctest2"
#define INPUT_TITLE1 "input image srctest1"
#define INPUT_TITLE2 "input image srctest2"
#include <iostream>
#include <math.h>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
string convertToString(double d);
int main()
{
// 加载图像
Mat src, srctest1, srctest2;
src = imread("lena.png");
srctest1 = imread("1.png");
srctest2 = imread("2.png");
// 判断图像是否为空
if (!src.data|| !srctest1.data|| !srctest2.data)
{
cout << "ERROR : could not load image.";
return -1;
}
// 显示原始图像
imshow("【src 原图】", src);
imshow("【srctest1 原图】", srctest1);
imshow("【srctest2 原图】", srctest2);
//从RGB色彩空间转化为HSV色彩空间
cvtColor(src, src, COLOR_BGR2HSV);
cvtColor(srctest1, srctest1, COLOR_BGR2HSV);
cvtColor(srctest2, srctest2, COLOR_BGR2HSV);
//定义直方图计算所需要的各种参数
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* ranges[] = { h_ranges, s_ranges };
int channels[] = { 0,1 };
// MatND 是 Mat的别名,方便区分经过
// 直方图计算处理后和输入图像
MatND hist_src;
MatND hist_srctest1;
MatND hist_srctest2;
//计算直方图并归一化处理
calcHist(&src, 1, channels, Mat(),
hist_src, 2, histSize, ranges, true, false);
normalize(hist_src, hist_src, 0, 1,
NORM_MINMAX, -1, Mat());
calcHist(&srctest1, 1, channels, Mat(),
hist_srctest1, 2, histSize, ranges, true, false);
normalize(hist_srctest1, hist_srctest1, 0, 1,
NORM_MINMAX, -1, Mat());
calcHist(&srctest2, 1, channels, Mat(),
hist_srctest2, 2, histSize, ranges, true, false);
normalize(hist_srctest2, hist_srctest2, 0, 1,
NORM_MINMAX, -1, Mat());
//直方图比较
double src_srctest1 = compareHist(hist_src,
hist_srctest1, HISTCMP_CORREL);
double src_srctest2 = compareHist(hist_src,
hist_srctest2, HISTCMP_CORREL);
double srctest1_srctest2 = compareHist(hist_srctest1,
hist_srctest2, HISTCMP_CORREL);
cout << "src compare with \
srctest1_srctest2 correlation value : "
<< srctest1_srctest2 << endl;
cout << "src compare with \
srctest1 correlation value : "
<< src_srctest1 << endl;
cout << "src compare with \
srctest2 correlation value : "
<< src_srctest2 << endl;
// 给每个图像上添加文字,内容为
// 该图片和原始图片的比较结果
putText(srctest1, convertToString(src_srctest1),
Point(50, 50), FONT_HERSHEY_COMPLEX, 1,
Scalar(0, 0, 255), 2, LINE_AA);
putText(srctest2, convertToString(src_srctest2),
Point(50, 50), FONT_HERSHEY_COMPLEX, 1,
Scalar(255, 0, 255), 2, LINE_AA);
putText(src, convertToString(srctest1_srctest2),
Point(50, 50), FONT_HERSHEY_COMPLEX, 1,
Scalar(0, 255, 255), 2, LINE_AA);
//图像的显示
namedWindow(INPUT_TITLE0, WINDOW_AUTOSIZE);
namedWindow(INPUT_TITLE1, WINDOW_AUTOSIZE);
namedWindow(INPUT_TITLE2, WINDOW_AUTOSIZE);
imshow(INPUT_TITLE0, src);
imshow(INPUT_TITLE1, srctest1);
imshow(INPUT_TITLE2, srctest2);
waitKey(0);
return 0;
}
string convertToString(double d) {
ostringstream os;
if (os<<d)
{
return os.str();
}
return "invalid conversion";
}
5、实验结果
三幅原图 原图与中间图像直方图的比较结果 原图与第三张图像直方图的比较结果 中间图像与第三张图像直方图的比较结果我是奕双,现在已经毕业将近两年了,从大学开始学编程,期间学习了C语言编程,C++语言编程,Win32编程,MFC编程,毕业之后进入一家图像处理相关领域的公司,掌握了用OpenCV对图像进行处理,如果大家对相关领域感兴趣的话,可以关注我,我这边会为大家进行解答哦!如果大家需要相关学习资料的话,可以私聊我哦!
网友评论