OpenCV4.8 开发实战系列专栏之 19 - 图像直方图比较

news2024/12/27 7:55:18

大家好,欢迎大家学习OpenCV4.8 开发实战专栏,长期更新,不断分享源码。

专栏代码全部基于C++ 与Python双语演示,领学习资料(Free) & 进交流答疑群,+ V: OpenCVXueTang_Asst

本文关键知识点:图像直方图比较

图像直方图比较,就是计算两幅图像的直方图数据,比较两组数据的相似性,从而得到两幅图像之间的相似程度,直方图比较在早期的CBIR中是应用很常见的技术手段,通常会结合边缘处理、词袋等技术一起使用。

OpenCV中直方图比较的API很简单

compareHist(hist1,hist2, method)
-常见比较方法有
相关性
卡方
交叉
巴氏

图像直方图比较是一种用于评估两个图像相似性的技术。直方图表示图像中像素值的分布,通过比较两个图像的直方图,可以推断它们之间的相似性。compareHist(hist1,hist2, method) 函数通常用于OpenCV库中,它提供了多种方法来比较两个直方图。以下是几种方法的解释:

  1. 相关性(Correlation)
    相关性方法测量两个直方图的相似度,其值范围在[-1, 1]之间。值越接近1,表示两个直方图越相似。相关性方法通过计算两个直方图之间的归一化互相关来衡量相似度。

    公式:
    [
    \text{Correlation}(H1, H2) = \frac{\sum_{I}(H1(I) - \bar{H1}) \cdot (H2(I) - \bar{H2})}{\sqrt{\sum_{I}(H1(I) - \bar{H1})^2 \cdot \sum_{I}(H2(I) - \bar{H2})^2}}
    ]
    其中, H 1 ( I ) H1(I) H1(I) H 2 ( I ) H2(I) H2(I) 是两个直方图在灰度级I的值, H 1 ˉ \bar{H1} H1ˉ H 2 ˉ \bar{H2} H2ˉ 是它们的平均值。

  2. 卡方(Chi-Square)
    卡方方法通过计算两个直方图之间的卡方统计量来衡量它们之间的差异。卡方值越小,表示两个直方图越相似。卡方方法更敏感于直方图中的较大差异。

    公式:
    [
    \text{Chi-Square}(H1, H2) = \sum_{I} \frac{(H1(I) - H2(I))^2}{H1(I) + H2(I)}
    ]

  3. 交叉(Intersection)
    交叉方法通过计算两个直方图交集的和来衡量它们的相似度。交集的和越大,表示两个直方图越相似。这种方法对于直方图中存在相同灰度级的频率较为敏感。

    公式:
    [
    \text{Intersection}(H1, H2) = \sum_{I} \min(H1(I), H2(I))
    ]

  4. 巴氏距离(Bhattacharyya Distance)
    巴氏距离是一种衡量两个概率分布之间相似度的度量。在直方图比较中,它用于测量两个直方图之间的相似度。巴氏距离越小,表示两个直方图越相似。

    公式:
    [
    \text{Bhattacharyya Distance}(H1, H2) = -\ln\left(\sum_{I} \sqrt{H1(I) \cdot H2(I)}\right)
    ]

在使用 compareHist 函数时,您可以选择上述方法之一作为参数 method 来比较两个直方图。例如,在OpenCV中,您可以通过以下方式调用该函数:

import cv2

# 假设 hist1 和 hist2 是已经计算好的两个直方图
similarity = cv2.compareHist(hist1, hist2, cv2.HISTCMP_CORREL)  # 使用相关性方法

选择哪种方法取决于您的具体应用和所需的相似度度量标准。

演示代码

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

using namespace cv;
using namespace std;

int main(int artc, char** argv) {
	Mat src1 = imread("D:/vcprojects/images/m1.png");
	Mat src2 = imread("D:/vcprojects/images/m2.png");
	Mat src3 = imread("D:/vcprojects/images/flower.png");
	Mat src4 = imread("D:/vcprojects/images/wm_test.png");

	imshow("input1", src1);
	imshow("input2", src2);
	imshow("input3", src3);
	imshow("input4", src4);

	Mat hsv1, hsv2, hsv3, hsv4;
	cvtColor(src1, hsv1, COLOR_BGR2HSV);
	cvtColor(src2, hsv2, COLOR_BGR2HSV);
	cvtColor(src3, hsv3, COLOR_BGR2HSV);
	cvtColor(src4, hsv4, COLOR_BGR2HSV);

	int h_bins = 60; int s_bins = 64;
	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 };
	Mat hist1, hist2, hist3, hist4;
	calcHist(&hsv1, 1, channels, Mat(), hist1, 2, histSize, ranges, true, false);
	calcHist(&hsv2, 1, channels, Mat(), hist2, 2, histSize, ranges, true, false);
	calcHist(&hsv3, 1, channels, Mat(), hist3, 2, histSize, ranges, true, false);
	calcHist(&hsv4, 1, channels, Mat(), hist4, 2, histSize, ranges, true, false);

	normalize(hist1, hist1, 0, 1, NORM_MINMAX, -1, Mat());
	normalize(hist2, hist2, 0, 1, NORM_MINMAX, -1, Mat());
	normalize(hist3, hist3, 0, 1, NORM_MINMAX, -1, Mat());
	normalize(hist4, hist4, 0, 1, NORM_MINMAX, -1, Mat());

	for (int i = 0; i < 4; i++)
	{
		int compare_method = i;
		double src1_src2 = compareHist(hist1, hist2, compare_method);
		double src3_src4 = compareHist(hist3, hist4, compare_method);
		printf(" Method [%d]  : src1_src2 : %f, src3_src4: %f,  \n", i, src1_src2, src3_src4);
	}

	waitKey(0);
	return 0;
}

python 代码演示

import cv2 as cv

src1 = cv.imread("D:/images/m1.png")
src2 = cv.imread("D:/images/m2.png")
src3 = cv.imread("D:/images/flower.png")
src4 = cv.imread("D:/images/test.jpg")

cv.imshow("input1", src1)
cv.imshow("input2", src2)
cv.imshow("input3", src3)
cv.imshow("input4", src4)

hsv1 = cv.cvtColor(src1, cv.COLOR_BGR2HSV)
hsv2 = cv.cvtColor(src2, cv.COLOR_BGR2HSV)
hsv3 = cv.cvtColor(src3, cv.COLOR_BGR2HSV)
hsv4 = cv.cvtColor(src4, cv.COLOR_BGR2HSV)

hist1 = cv.calcHist([hsv1], [0, 1], None, [60, 64], [0, 180, 0, 256])
hist2 = cv.calcHist([hsv2], [0, 1], None, [60, 64], [0, 180, 0, 256])
hist3 = cv.calcHist([hsv3], [0, 1], None, [60, 64], [0, 180, 0, 256])
hist4 = cv.calcHist([hsv4], [0, 1], None, [60, 64], [0, 180, 0, 256])
print(hist1.dtype)

cv.normalize(hist1, hist1, 0, 1.0, cv.NORM_MINMAX, dtype=cv.CV_32F)
cv.normalize(hist2, hist2, 0, 1.0, cv.NORM_MINMAX)
cv.normalize(hist3, hist3, 0, 1.0, cv.NORM_MINMAX)
cv.normalize(hist4, hist4, 0, 1.0, cv.NORM_MINMAX)

methods = [cv.HISTCMP_CORREL, cv.HISTCMP_CHISQR,
           cv.HISTCMP_INTERSECT, cv.HISTCMP_BHATTACHARYYA]
str_method = ""
for method in methods:
    src1_src2 = cv.compareHist(hist1, hist2, method)
    src3_src4 = cv.compareHist(hist3, hist4, method)
    if method == cv.HISTCMP_CORREL:
        str_method = "Correlation"
    if method == cv.HISTCMP_CHISQR:
        str_method = "Chi-square"
    if method == cv.HISTCMP_INTERSECT:
        str_method = "Intersection"
    if method == cv.HISTCMP_BHATTACHARYYA:
        str_method = "Bhattacharyya"

    print("%s src1_src2 = %.2f, src3_src4 = %.2f"%(str_method, src1_src2, src3_src4))

cv.waitKey(0)
cv.destroyAllWindows()

结束语

学习贵在坚持,学习OpenCV贵在每一天的代码练习,原理跟基本的函数解释,相关知识,后续更新边学边理解,搞技术永远要坚持做长期主义者!我们一起努力!!!

注:领学习资料(Free) & 进交流答疑群,+ V: OpenCVXueTang_Asst

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2254566.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python学习——数据的验证

文章目录 1. str.isdigit()2. str.isnumeric()3. str.isalpha()4. str.isalnum()5. str.islower()6. str.isupper()7. str.istitle()8. str.isspace()实操 以下是Python中字符串数据验证方法的详细解释&#xff1a; 1. str.isdigit() 这个方法用于检查字符串中的所有字符是否都…

基于Springboot+Vue的在线答题闯关系统

基于SpringbootVue的在线答题闯关系统 前言&#xff1a;随着在线教育的快速发展&#xff0c;传统的教育模式逐渐向互联网教育模式转型。在线答题系统作为其中的一个重要组成部分&#xff0c;能够帮助用户通过互动式的学习方式提升知识掌握度。本文基于Spring Boot和Vue.js框架&…

Web(CSS+JS+HTML实现简单界面)

前言 写的是个人博客界面&#xff0c;代码比较冗余&#xff0c;web的一个小作业。。。。。。 因为后面改了一次&#xff0c;有些css是直接写到了html文件中&#xff0c;重复的代码也比较多。 项目结构 CSS style.css * {margin: 0;padding: 0;box-sizing: border-box; }b…

Scala:正则表达式

object test03 {//正则表达式def main(args: Array[String]): Unit {//定义一个正则表达式//1.[ab]:表示匹配一个字符&#xff0c;或者是a&#xff0c;或者是b//2.[a-z]:表示从a到z的26个字母中的任意一个//3.[A-Z]:表示从A到Z的26个字母中的任意一个//4.[0-9]:表示从0到9的10…

经验帖 | Matlab安装成功后打不开的解决方法

最近在安装Matlab2023时遇到了一个问题&#xff1a; 按照网上的安装教程成功安装 在打开软件时 界面闪一下就消失 无法打开 但是 任务管理器显示matlab在运行中 解决方法如下&#xff1a; matlab快捷方式–>右键打开属性–>目标 填写许可证文件路径 D:\MATLAB\MatlabR20…

VCU——matlab/simulink软件建模

一、认识MATLAB/Simulink 1. matlab主界面 2. simulink 二、Simulink 建模基础 1. Simulink模块 2. 模型的仿真 matlab 中比较两个浮点型&#xff0c;不要用&#xff0c;采取差值和Compare To Constant的方案 3. 自动代码生成

(软件测试文档大全)测试计划,测试报告,测试方案,压力测试报告,性能测试,等保测评,安全扫描测试,日常运维检查测试,功能测试等全下载

1. 引言 1.1. 编写目的 1.2. 项目背景 1.3. 读者对象 1.4. 参考资料 1.5. 术语与缩略语 2. 测试策略 2.1. 测试完成标准 2.2. 测试类型 2.2.1. 功能测试 2.2.2. 性能测试 2.2.3. 安全性与访问控制测试 2.3. 测试工具 3. 测试技术 4. 测试资源 4.1. 人员安排 4.2. 测试环境 4.2.…

Crash-SQLiteDiskIOException

目录 相关问题 日志信息 可能原因 问题排查 相关问题 蓝牙wifi无法使用 日志信息 可能原因 磁盘空间不足&#xff1a;当设备上的可用存储空间不足时&#xff0c;SQLite无法完成磁盘I/O操作&#xff0c;从而导致SQLiteDiskIOException。 数据库文件损坏&#xff1a;如果数…

PyTorch 深度学习框架简介:灵活、高效的 AI 开发工具

PyTorch 深度学习框架简介&#xff1a;灵活、高效的 AI 开发工具 PyTorch 作为一个深度学习框架&#xff0c;以其灵活性、可扩展性和高效性广受欢迎。无论是在研究领域进行创新实验&#xff0c;还是在工业界构建生产级的深度学习模型&#xff0c;PyTorch 都能提供所需的工具和…

Java Web 4 Maven

本文详细介绍了Maven的用途&#xff0c;包括依赖管理、项目结构统一和构建流程标准化&#xff1b;然后讲解了Maven的安装、IDEA中的集成以及依赖管理的核心概念。 1 什么是Maven&#xff1f; 什么是apache&#xff1f; 2 Maven的作用 &#xff08;1&#xff09;方便依赖管理 有…

无人机吊舱类型详解!

一、侦察与监测类吊舱 电子侦察吊舱 功能&#xff1a;主要用于侦察和监测目标&#xff0c;具备侦察、监听、干扰等多种功能。 设备&#xff1a;通常安装有电子侦察设备和通信设备&#xff0c;可以实时获取目标的电子信息&#xff0c;并将数据传输回地面指挥中心。 应用&…

数据结构与算法之美:顺序表详解

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《题海拾贝》、《编程之路》、《数据结构与算法之美》 欢迎点赞、关注&#xff01; 1、 什么…

Neo4j 图数据库安装与操作指南(以mac为例)

目录 一、安装前提条件 1.1 Java环境 1.2 Homebrew&#xff08;可选&#xff09; 二、下载并安装Neo4j 2.1 从官方网站下载 2.1.1 访问Neo4j的官方网站 2.1.2 使用Homebrew安装 三、配置Neo4j 3.1 设置环境变量(可选) 3.2 打开配置文件(bash_profile) 3.2.1 打开终端…

Linux centOS 7 安装 rabbitMQ

1.安装前需要了解&#xff0c;rabbitmq安装需要先安装erlang&#xff0c;特别注意的是erlang与rabbitmq的版本之间需要匹配。 el/7/rabbitmq-server-3.10.0-1.el7.noarch.rpm - rabbitmq/rabbitmq-server packagecloud 3.10版本的rabbitmq 对于erlang的版本要求可以看此连接…

SpringBoot整合Mockito进行单元测试超全详细教程 JUnit断言 Mockito 单元测试

Mock概念 Mock叫做模拟对象&#xff0c;即用来模拟未被实现的对象可以预先定义这个对象在特定调用时的行为&#xff08;例如返回值或抛出异常&#xff09;&#xff0c;从而模拟不同的系统状态。 导入Mock依赖 pom文件中引入springboot测试依赖&#xff0c;spring-boot-start…

QT 中 sqlite 数据库使用

一、前提 --pro文件添加sql模块QT core gui sql二、使用 说明 --用于与数据库建立连接QSqlDatabase--执行各种sql语句QSqlQuery--提供数据库特定的错误信息QSqlError查看qt支持的驱动 QStringList list QSqlDatabase::drivers();qDebug()<<list;连接 sqlite3 数据库 …

微信小程序配置less并使用

1.在VScode中下载Less插件 2.在微信小程序中依次点击如下按钮 选择 从已解压的扩展文件夹安装… 3.选中刚在vscode中下载安装的插件文件 如果没有修改过插件的安装目录&#xff0c;一般是在c盘下C:\用户\用户名.vscode\extensions\mrcrowl.easy-less-2.0.2 我的路径是&#xf…

ClouderaManager 集群搭建

前提&#xff1a;服务器之前做过域名映射、免密登录 ClouderaManager 集群 1. 组件分布规划 服务器服务器h1zk、hdfs(dn)、yarn(nm)、spark、kafka、flumeh2hdfs(nn-standy)、yarn(rm-active)、sparkh3hdfs(nn-active)、yarn(rm-standy)、hive、sparkh4zk、hdfs(dn)、yarn(n…

OpenHarmony-3.HDF框架(2)

OpenHarmony HDF 平台驱动 1.平台驱动概述 系统平台驱动框架是系统驱动框架的重要组成部分&#xff0c;它基于HDF驱动框架、操作系统适配层(OSAL, operating system abstraction layer)以及驱动配置管理机制&#xff0c;为各类平台设备驱动的实现提供标准模型。 系统平台驱动(…

Guiding a Diffusion Model with a Bad Version of Itself

Guiding a Diffusion Model with a Bad Version of Itself Abstract1. Introduction2. Background3. Why does CFG improve image quality?Score matching leads to outliers.CFG 消除异常值Discussion 4 Our method Abstract 在图像生成扩散模型中&#xff0c;主要关注的轴心…