OpenCV图像处理学习二十一,直方图比较方法

2023-05-16

一.直方图比较

直方图比较是对输入的两张图像进行计算得到直方图H1与H2,归一化到相同的尺度空间,然后可以通过计算H1与H2的之间的距离得到两个直方图的相似程度(每张图像都有唯一的直方图与之对应),进而比较图像本身的相似程度。Opencv提供的比较方法有四种:

Correlation 相关性比较

Chi-Square 卡方比较

Intersection 十字交叉性

Bhattacharyya distance 巴氏距离。

(1)直方图比较方法-相关性计算(CV_COMP_CORREL)

             d\left ( h_{1},h_{2} \right ) =\frac{\sum _{I}\left ( H_{1}\left ( I \right )-\bar{H} _{1}\right )\left ( H_{2}\left ( I \right )-\bar{H} _{2}\right )}{\sqrt{\sum _{I}\left ( H_{1}\left ( I \right )-\bar{H}_{1} \right )^{2}\sum _{I}\left ( H_{2} \left ( I \right )-\bar{H_{2}}\right )^{2}}}

其中:                     \bar{H}_{k} = \frac{1}{N}\sum_{j}^{}H_{k}\left ( J \right )  

其中N是直方图的BIN个数,\bar{H}是均值。

---------------------------------------------------------------------------------------------------------------------------------

(2)直方图比较方法-相关性计算(CV_COMP_CORREL)

             d\left ( h_{1},h_{2} \right ) = \sum_{I}^{}\frac{\left ( H_{1}\left ( I \right )-\bar{H}_{2} \right )^{2}}{H_{1\left ( I \right )}}

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

---------------------------------------------------------------------------------------------------------------------------------

(3)直方图比较方法-十字交叉性计算(CV_COMP_INTERSECT)

            d\left ( h_{1},h_{2} \right ) = \sum_{I}^{}min\left ( H_{1}\left ( I \right ) ,H_{2}\left ( I \right )\right )

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

--------------------------------------------------------------------------------------------------------------------------------

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

         d\left ( h_{1},h_{2} \right ) = \sqrt{1- \frac{1}{\sqrt{\bar{H}_{1}\bar{H}_{2}N^{2}}}\sum_{j}^{}\sqrt{H_{1}\left ( I \right )H_{2}\left ( I \right )}}

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

---------------------------------------------------------------------------------------------------------------------------------

二.图像直方图比较方法

  • 加载原图像
  • 将图像色彩空间由BGR三通道转换为HSV空间(由于直方图对亮度和灰度比较敏感,色彩空间转换就是突出这两个因素尽量去除其他因素)
  • 计算直方图进行归一化处理,归一化到0到1之间,调用calcHistnormalize
  • 直方图比较,使用上述四种方法之一,调用compareHist

直方图比较API函数接口

#API接口
double compareHist(InputArray h1,InputArray H2,int method)
//参数说明:
第一个参数InputArray类型 h1,直方图数据
第二个参数InputArray类型 h2,直方图数据
第三个参数int类型 method比较方法,上述四种方法之一

返回值:采用上述四中方法之一计算后的两个直方图相关系数

关于 int method 的取值:

enum HistCompMethods {
    HISTCMP_CORREL        = 0,    //相关性比较
    HISTCMP_CHISQR        = 1,    //卡方比较
    HISTCMP_INTERSECT     = 2,    //十字交叉性
    HISTCMP_BHATTACHARYYA = 3,    //巴氏距离
    HISTCMP_HELLINGER     = HISTCMP_BHATTACHARYYA, 
    HISTCMP_CHISQR_ALT    = 4,    //替代卡方:通常用于纹理比较。
    HISTCMP_KL_DIV        = 5     //KL散度
};

不同直方图相关性比较方法的特点:

Correlation相关性比较(CV_COMP_CORREL)值越大,相关度越高,最大值为1,最小值为0,越接近1越相似
Chi-Square卡方比较(CV_COMP_CHISQR) 值越小,相关度越高,最大值无上界,最小值0,越接近0越相似
Intersection十字交叉性(CV_COMP_INTERSECT)对于相似度比较,值越大,表明相关度越高,最大值无上界;完美匹配为1,完全不匹配为0;
Bhattacharyya distance巴氏距离(CV_COMP_BHATTACHARYYA)值越小,相关度越高,最大值为1,最小值为0,越接近1越相似

=========================================================================

代码实现

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

using namespace std;
using namespace cv;

string convertToString(double d);
int main(int argc, char** argv) {
	Mat base, test1, test2;          //RGB图像
	Mat hsvbase, hsvtest1, hsvtest2; //HSV图像
	base = imread("F:/photo/zx.jpg");
	if (!base.data) {
		printf("could not load image...\n");
		return -1;
	}
	test1 = imread("F:/photo/a.jpg");
	test2 = imread("F:/photo/c.jpg");
	//转化为HSV图像
	cvtColor(base, hsvbase, COLOR_BGR2HSV);
	cvtColor(test1, hsvtest1, COLOR_BGR2HSV);
	cvtColor(test2, hsvtest2, COLOR_BGR2HSV);

	int h_bins = 50; int s_bins = 60;
	int histSize[] = { h_bins, s_bins };
	// hue varies from 0 to 179, saturation from 0 to 255     
	float h_ranges[] = { 0, 180 };
	float s_ranges[] = { 0, 256 };
	const float* ranges[] = { h_ranges, s_ranges };
	// Use the o-th and 1-st channels     
	int channels[] = { 0, 1 };
	MatND hist_base;
	MatND hist_test1;
	MatND hist_test2;

	calcHist(&hsvbase, 1, channels, Mat(), hist_base, 2, histSize, ranges, true, false);
	normalize(hist_base, hist_base, 0, 1, NORM_MINMAX, -1, Mat());

	calcHist(&hsvtest1, 1, channels, Mat(), hist_test1, 2, histSize, ranges, true, false);
	normalize(hist_test1, hist_test1, 0, 1, NORM_MINMAX, -1, Mat());

	calcHist(&hsvtest2, 1, channels, Mat(), hist_test2, 2, histSize, ranges, true, false);
	normalize(hist_test2, hist_test2, 0, 1, NORM_MINMAX, -1, Mat());

	double basebase = compareHist(hist_base, hist_base, 2);//zx
	double basetest1 = compareHist(hist_base, hist_test1,2);//zx and a
	double basetest2 = compareHist(hist_base, hist_test2, 2);//zx and c
	double tes1test2 = compareHist(hist_test1, hist_test2, 2);//a and c
	printf("test1 compare with test2 correlation value :%f", tes1test2);

	Mat test12;
	test2.copyTo(test12);
	putText(base, convertToString(basebase), Point(50, 50), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 2, LINE_AA);  //zx
	putText(test1, convertToString(basetest1), Point(50, 50), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 2, LINE_AA);//zx and a
	putText(test2, convertToString(basetest2), Point(50, 50), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 2, LINE_AA);//zx and c
	putText(test12, convertToString(tes1test2), Point(50, 50), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 2, LINE_AA);//a and c

	namedWindow("base", 0);
	resizeWindow("base", base.cols / 2, base.rows / 2);
	namedWindow("test1", 0);
	resizeWindow("test1", test1.cols / 2, test1.rows / 2);
	namedWindow("test2", 0);
	resizeWindow("test2", test2.cols / 2, test2.rows / 2);

	imshow("base", base);
	imshow("test1", test1);
	imshow("test2", test2);
	imshow("test12", test12);

	waitKey(0);
	return 0;
}

string convertToString(double d) {
	ostringstream os;
	if (os << d)
		return os.str();
	return "invalid conversion";
}

---------------------------------------------------------------------------------------------------------------------------------

图像处理效果

代码中,车道线图片base自行十字交叉性比较,basebase = 36.8538,数值越大,图像相关性程度越高 

base图片与test1图片进行十字交叉性比较,test1base = 9.55181,数值较小,图像相识度较低

下面图像是test1图像与test2图像直方图对比,test2base = 7.98399,相识度较小

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenCV图像处理学习二十一,直方图比较方法 的相关文章

  • Bounding box(bbox) 预测

    在出现Bounding box预测之前 xff0c 一般都是通过滑动窗口进行目标检测 本文前两部分介绍滑动窗口算法 xff0c 这样是为了更好介绍 bounding box如何引出 为了解决什么问题而引出的 也可直接跳跃到第三部分看有关bo
  • YOLOv3网络结构分析以及工作流程

    注意 xff1a 本文章有很多图 xff0c 但是都是YOLOv3的结构图 xff0c 只是每张图表达出的信息都各有特色 xff0c 可将这些结构图结合起来 xff0c 能更好的理解 1 Darknet 53 模型结构 在论文中虽然有给网络
  • Qt中QDebug的使用

    QDebug类为调试信息 debugging information 提供输出流 它的声明在 lt QDebug gt 中 xff0c 实现在Core模块中 将调试或跟踪信息 debugging or tracing information
  • Ubuntu18.04安装教程——超详细的图文教程

    电脑配置 xff1a 名称 xff1a Lenovo 拯救者Y7000P 处理器 xff1a i7 10750H 内存 xff1a 32G 固态 xff1a 1TB 显卡 xff1a RTX2060 6G 一 准备工作 本文以 Ubuntu
  • Ubuntu18.04启动后无法进入桌面修复方法(图文)

    引言 xff08 吐槽可略过 xff09 xff1a Ubuntu是应用广泛的Linux操作系统 xff0c 特别是在机器学习应用中 xff0c 通过调用NVIDIA显卡的GPU进行计算和研究的主要平台之一 但是由于NV显卡的存在 xff0
  • VINS-Course代码解析——run_euroc前端数据处理

    vins mono总框架如下 xff1a 主要分为三大块 xff1a 我们先从主函数 main 入手 xff1a 主函数中有三个线程 xff0c 读取完数据集和配置文件的路径后就会进入这三个线程 xff0c 如下图 xff1a thd Ba
  • Gazebo11的更新与安装

    Melodic自带的Gazebo版本过低 xff0c 建议升级 Gazebo安装见gazebo官网 需注意以下四点 删除gazebo9以及相关插件选用Alternative installation step by step的安装方式 xf
  • XTDrone目标检测

    编译Darkent ROS 方法一 xff1a xff08 推荐 xff09 直接clone xff0c 记得加 recurse submodules xff0c 防止文件缺失 cd span class token operator sp
  • C++求解N个数的最大公约数、最小公倍数

    一 2个数的最大公约数 span class token comment 辗转相除法 span span class token keyword int span span class token function gcd span spa
  • 子序列个数——动态规划

    题目 xff1a 统计一个字符串中全部不同的子序列的个数 思路 xff1a 动态规划求解 令 f i 61 前 i 个元素中包含的全部子序列的个数 那么状态转移方程分为下面两种情况 xff1a 当第 i 个元素在前面 i 1 个字符中没有出
  • 字符串中特定子序列出现的次数(动态规划)

    题目 xff1a 给定一个字符串 xff0c 求子序列 cwbc 出现的次数 思路 xff1a 动态规划 令 dp i j 表示前 i 个字符中匹配了字符串 cwbc 中前 j 位 xff08 j 61 1 2 3 4 xff09 的个数
  • VMware ubuntu虚拟机无法上网的解决办法(笔记本连接WIFI情况)

    文章目录 一 虚拟机网络配置 一 虚拟机网络配置 1 设置Ubuntu网络适配器的网络连接方式为NAT模式 2 还原虚拟机网络配置 还原一下默认设置 3 window网络适配器设置适配器允许网络共享 4 Ubuntu启用联网 xff0c 连
  • ubuntu在树梅派上之VNC

    启动vncserver vncserver span class token operator span geometry 1600x900 杀死第一个桌面 vncserver span class token operator span
  • Sourcetree介绍及使用

    Sourcetree是一个操作简单但功能强大的免费Git客户端管理工具 xff0c 可应用在Windows和Mac平台 Sourcetree的安装 xff1a 1 从Sourcetree Free Git GUI for Mac and W
  • javascript创建一个基于数组的栈结构

    栈是一种遵从后进先出 xff08 LIFO xff09 原则的有序集合 新添加或待删除的元素都保存在栈的同 一端 xff0c 称作栈顶 xff0c 另一端就叫栈底 在栈里 xff0c 新元素都靠近栈顶 xff0c 旧元素都接近栈底 栈拥有以
  • Ubuntu16.04+RealsenseT265跑通VINS-Fusion

    一 提前条件 系统版本 xff1a ubuntu16 04 43 ROS xff08 kinetic xff09 默认已经掌握了ubuntu系统下的基本命令以及ROS的基本操作 二 realsenseT265的SDK测试 官方网站https
  • Why Kubernetes ,我对Kubernetes的理解

    去年换工作后 xff0c 开始真正在生产环境中接触容器与Kubernetes 边恶补相关知识的同时 xff0c 也想把学到的内容和自己的理解整理出来 学习的途径包括k8s官方文档 书籍 极客时间专栏及网上各种博文 所涉及一些摘抄或描述 xf
  • Kubernetes的几种主流部署方式01-minikube部署

    综述 Kubernetes集群的组件众多 xff0c 要部署一套符合生产环境的集群不是一件容易的事 好在随着社区的快速发展 xff0c 特别是在它成为事实上的容器编排标准以后 xff0c 基本所有的主流云平台都完全支持Kubernetes
  • Kubernetes 1.14版本的亮点新功能

    部分翻译自https sysdig com blog whats new kubernetes 1 14 Kubernetes 1 14的亮点新功能 xff1a 支持Windows容器服务可以通过kubeadm动态地创建一个高可用集群将ku
  • Kubernetes的几种主流部署方式02-kubeadm部署1.14版本高可用集群

    在上篇文章minikube部署中 xff0c 有提到Minikube部署Kubernetes的核心就是Kubeadm xff0c 这篇文章来详细说明下Kubeadm原理及部署步骤 写这篇文章的时候 xff0c Kubernetes1 14刚

随机推荐