设为首页收藏本站 |天气与日历| 2025-08-23 星期六 07:07:00 乙巳(蛇)年 七月初一 辰时 处暑
     
切换到窄版

私人站点

 找回密码
 立即注册
搜索
查看: 309|回复: 0

直方图比较

[复制链接]

954

主题

954

帖子

3879

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3879
发表于 2022-3-10 09:39:22 | 显示全部楼层 |阅读模式
直方图比较方法-概述

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





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




直方图比较方法-卡方计算(CV_COMP_CHISQR)

4.png
H1,H2分别表示两个图像的直方图数据





直方图比较方法-十字计算(CV_COMP_INTERSECT)

5.png
H1,H2分别表示两个图像的直方图数据



直方图比较方法-巴氏距离计算(CV_COMP_BHATTACHARYYA )

6.png
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 "无效转换";
}


aaaa.jpg






回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|编程站点 ( 冀ICP备2023028127号-2 )|友链申请|

GMT+8, 2025-8-23 07:07 , Processed in 0.097252 second(s), 25 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表