OpenCV学习笔记(十二)之直方图比较

本文章由公号【开发小鸽】发布!欢迎关注!!!


老规矩–妹妹镇楼:

一. 直方图比较方法

       对输入的两张图像计算得到直方图H1和H2,归一化到相同的尺度空间,然后通过计算H1和H2之间的距离得到两个直方图的相似程度。

二. OpenCV提供的比较方法:

  1. Correlation - 相关性比较
  2. Chi-Square - 卡方比较
  3. Intersection - 十字交叉性
  4. Bhattacharyya - 巴氏距离

(一).相关性比较(HISTCOM_CORREL)

(二).卡方比较(HISTCOM_CHISQE)

(三). 十字交叉性(HISTCOM_INTERSECT)

(四). 巴氏距离(HISTCOM_BHATTACHARYYA)

三. API分析

cv::compareHist(
	InputArray h1,		//直方图数据
	InputArray h2,
	int method,			//比较方法
)

四. 代码实现:

/*****直方图比较*****/

#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>

using namespace std;

string DoubleToString(double b);

int main(int argc, char** argv) {
	cv::Mat src1, src2, src3;			//测试三张图片的相似度
	src1 = cv::imread("1.jpg");
	src2 = cv::imread("10.jpg");
	src3 = cv::imread("10.png");

	//将RGB空间转为HSV空间
	cv::cvtColor(src1, src1, cv::COLOR_BGR2HSV);
	cv::cvtColor(src2, src2, cv::COLOR_BGR2HSV);
	cv::cvtColor(src3, src3, cv::COLOR_BGR2HSV);
	
	//准备直方图的参数
	//两维的直方图
	int h_bins = 50;		//H的直方图的尺寸
	int s_bins = 60;		//S的直方图的尺寸
	int histSize[] = { h_bins, s_bins };

	//直方图的变化范围
	float h_ranges[] = { 0, 180 };	//H的变化范围
	float s_ranges[] = { 0, 256 };	//S的变化范围
	const float* ranges[] = { h_ranges, s_ranges };

	//二维的直方图使用两个通道0, 1
	int channels[] = { 0, 1 };
	//直方图数据
	cv::MatND hist_src1;
	cv::MatND hist_src2;
	cv::MatND hist_src3;

	//生成直方图,并将数据归一化到0-1之间
	cv::calcHist(&src1, 1, channels, cv::Mat(), hist_src1, 2, histSize,
		ranges, true, false);
	cv::calcHist(&src2, 1, channels, cv::Mat(), hist_src2, 2, histSize,
		ranges, true, false);
	cv::calcHist(&src3, 1, channels, cv::Mat(), hist_src3, 2, histSize,
		ranges, true, false);
	//归一化
	cv::normalize(hist_src1, hist_src1, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());
	cv::normalize(hist_src2, hist_src2, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());
	cv::normalize(hist_src3, hist_src3, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());

	//求出直方图的数据后,就可以进行比较了
	double src1_2 = cv::compareHist(hist_src1, hist_src2, cv::HISTCMP_CORREL);
	double src1_3 = cv::compareHist(hist_src1, hist_src3, cv::HISTCMP_CORREL);
	double src2_3 = cv::compareHist(hist_src2, hist_src3, cv::HISTCMP_CORREL);

	cout << "src1 compares with src2 correlation value: " << src1_2 << endl;
	cout << "src1 compares with src3 correlation value: " << src1_3 << endl;
	cout << "src2 compares with src3 correlation value: " << src2_3 << endl;

	//将比较数值显示到图像上
	cv::putText(src1, DoubleToString(src1_2), cv::Point(50, 50),
		cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(0, 0, 255), 2, cv::LINE_AA);
	cv::putText(src2, DoubleToString(src2_3), cv::Point(50, 50),
		cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(0, 0, 255), 2, cv::LINE_AA);
	
	cv::namedWindow("src1_1", cv::WINDOW_NORMAL);
	cv::namedWindow("src1_2", cv::WINDOW_NORMAL);

	cv::imshow("src1_2", src1);
	cv::imshow("src2_3", src2);

	cv::waitKey(0);
	return 0;

}

//Doublle 转 String
string DoubleToString(double b) {
	ostringstream os;
	if (os << b)
		return os.str();
	return "invalid value";  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值