Opencv学习-直方图比较

news2024/11/13 9:43:04
        由于图像的直方图表示图像像素灰度值的统计特性,因此可以通过两幅图像的直方图特性比较 两幅图像的相似程度。从一定程度上来讲,虽然两幅图像的直方图分布相似不代表两幅图像相似,但是两幅图像相似则两幅图像的直方图分布一定相似。例如,在通过插值对图像进行缩放后,虽然图像的直方图不会与之前完全一致,但是两者之间一定具有很高的相似性,因而可以通过比较两幅图像的直方图分布相似性对图像进行初步的筛选与识别。
        OpenCV 4 中提供了用于比较两个图像直方图相似性的 compareHist() 函数。

1.  compareHist()函数原型

double cv::compareHist(InputArray H1, 
InputArray H2, 
int method 
)
  • H1:第一幅图像直方图。
  • H2:第二幅图像直方图,与 H1 具有相同的尺寸。
  • method:比较方法标志。 
        该函数前两个参数为需要比较相似性的图像直方图,由于不同尺寸的图像中像素数目可能不相同,为了能够得到两个图像直方图正确的相似性,需要输入同一种方式归一化后的图像直方图,并且要求两个图像直方图具有相同的尺寸。该函数中第三个参数为比较相似性的方法,选择不同的方法会得到不同的相似性系数,会将计算得到的相似性系数以 double 类型返回。由于不同计算方法的规则不一,因此相似性系数代表的含义也不相同。接下来介绍每种方法比较相似性的原理。
compareHist()函数比较直方图方法的可选择标志参数

1.1 HISTCMP_CORREL 

        该方法名为相关法, 在该方法中,如果两个图像直方图完全一致,那么计算数值为 1 ;如果两个图像直方图完全不相关,那么计算值为 0

        其中,N 是直方图的灰度值个数。 

1.2 HISTCMP_CHISQR

        该方法名为卡方法,在该方法中,如果两个图像直方图完全一致,那么计算数值为 0;两个图像的相似性越小,计算数值越大。

1.3 HISTCMP_INTERSECT 

        该方法名为直方图相交法, 该方法不会将计算结果归一化,因此,即使是两个完全一致的图像直方图,来自于不同图像,也会有不同的数值。例如,由A 图像缩放后得到的两个完全一样的直方图相似性结果与由 B 图像缩放后得到的两个完全一样的直方图相似性结果可能不相同。但是,当任意图像的直方图与 A 图像的直方图比较时,数值越大, 相似性越高,数值越小,相似性越低。

1.4 HISTCMP_BHATTACHARYYA  

        该方法名为巴塔恰里雅距离(巴氏距离)法, 在该方法中,如果两个图像直方图完全一致,那么计算数值为 0 ;两个图像的相似性越小,计算数值越大。

1.5 HISTCMP_CHISQR_ALT 

        该方法称为替代卡方法,其判断两个直方图是否相似的方法与巴氏距离法相同,常用于替代巴氏距离法用于纹理比较。

1.6 HISTCMP_KL_DIV 

        该方法名为相对熵法,又名 Kullback-Leibler 散度法, 在该方法中,如果两个图像直方图完全一致,那么计算数值为 0 ;两个图像的相似性越小,计算数值越大。

2. 示例代码

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

using namespace cv; 
using namespace std; 

void drawHist(Mat &hist, int type, string name) //归一化并绘制直方图函数
{ 
    int hist_w = 512; 
    int hist_h = 400; 
    int width = 2; 
    Mat histImage = Mat::zeros(hist_h, hist_w, CV_8UC3); 
    normalize(hist, hist, 1, 0, type, -1, Mat()); 
    for (int i = 1; i <= hist.rows; i++) 
    { 
        rectangle(histImage, Point(width*(i - 1), hist_h - 1), 
        Point(width*i - 1, hist_h - cvRound(hist_h*hist.at<float>(i - 1)) - 1), 
        Scalar(255, 255, 255), -1); 
    } 
    imshow(name, histImage); 
} 
//主函数
int main() 
{ 
    //system("color F0"); //更改输出界面颜色
    Mat img = imread("../pic/gril_1.jpg"); 
    if (img.empty()) 
    { 
        cout << "请确认图像文件名称是否正确" << endl; 
        return -1; 
    } 
    Mat gray, hist, gray2, hist2, gray3, hist3; 
    cvtColor(img, gray, COLOR_BGR2GRAY); 
    resize(gray, gray2, Size(), 0.5, 0.5); 
    gray3 = imread("../pic/hand.jpg", IMREAD_GRAYSCALE); 
    const int channels[1] = { 0 }; 
    float inRanges[2] = { 0,255 }; 
    const float* ranges[1] = { inRanges }; 
    const int bins[1] = { 256 }; 
    calcHist(&gray, 1, channels, Mat(), hist, 1, bins, ranges); 
    calcHist(&gray2, 1, channels, Mat(), hist2, 1, bins, ranges); 
    calcHist(&gray3, 1, channels, Mat(), hist3, 1, bins, ranges); 
    drawHist(hist, NORM_INF, "hist"); 
    drawHist(hist2, NORM_INF, "hist2"); 
    drawHist(hist3, NORM_INF, "hist3"); 
    //原图直方图与原图直方图的相关系数
    double hist_hist = compareHist(hist, hist, HISTCMP_CORREL); 
    cout << "apple_apple=" << hist_hist << endl; 
    //原图直方图与缩小原图后的直方图的相关系数
    double hist_hist2 = compareHist(hist, hist2, HISTCMP_CORREL); 
    cout << "apple_apple256=" << hist_hist2 << endl; 
    //两幅不同图像直方图相关系数
    double hist_hist3 = compareHist(hist, hist3, HISTCMP_CORREL); 
    cout << "apple_lena=" << hist_hist3 << endl; 
    waitKey(0); 
    return 0; 
}

3. 测试结果 

 

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

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

相关文章

Openlayer - vue中加载天地图(入门篇)

在vue中安装openlayers npm i --save ol这里说的vue是基于脚手架构建的。 新建个页面&#xff0c;也就是vue文件&#xff0c;配置好路由。接着 就是可以直接放入我的代码运行显示了。 vue利用openlayers加载天地图和高德地图 <template><div class"wrapper&quo…

集团数字化转型方(五)

集团数字化转型方案通过全面整合人工智能&#xff08;AI&#xff09;、大数据分析、云计算和物联网&#xff08;IoT&#xff09;等前沿技术&#xff0c;构建了一个高度智能化的业务平台&#xff0c;从而实现业务流程的自动化、数据驱动的决策支持、精准的市场预测、以及个性化的…

web常见漏洞——XSS

xss 1、xss概述2、环境工具3、反射型xss3.1、利用反射型xss获取cookie 4、DOM型xss4.1、第一关4.2、第二关4.3、第三关4.4、第四关4.5、第五关4.6、第六关4.7、第七关4.8、第八关 5、存储型xss 1、xss概述 XSS全称跨站脚本(Cross Site Scripting)&#xff0c;为避免与层叠样式表…

视频孪生技术在智慧水利(水务)场景中的典型应用展示

一、智慧水利建设规划 根据水利部编制《“十四五”智慧水利建设规划》&#xff0c;建设数字孪生流域、“2N”水利智能业务应用体系、安全可控水利网络安全防护体系、优化健全水利网信保障体系&#xff0c;建成七大江河数字孪生流域&#xff0c;推进水利工程智能化改造&#xf…

C程序设计——常量

前面讲了变量&#xff0c;我们现在讲C语言的常量。 整数、自然数常量 十进制 就好像生活中&#xff0c;如果写一个数字&#xff0c;大家都默认是十进制&#xff0c;在C语言里也一样&#xff0c;比如&#xff1a; int main(void) {int iInt ;iInt 10;printf("%d\r\n&q…

无人机电子调速器详解!!!

电子调速器是无人机动力系统中的关键组件&#xff0c;主要负责将电池提供的直流电转换为交流电&#xff0c;并精确控制电机的转速&#xff0c;从而实现对无人机飞行状态的精确控制。以下是对无人机电子调速器的详细解析&#xff1a; 一、基本功能与原理 功能&#xff1a; 直…

R语言:如何安装包“linkET”

自己在R语言中安装包“linkET”时报错不存在叫‘linket’这个名字的程辑包 尝试了install.packages("linkET")和BiocManager::install("linkET")两种安装办法都不行 >install.packages("linkET") WARNING: Rtools is required to build R pa…

挑选知识库管理软件?9大推荐让你不再纠结

这篇文章介绍了以下工具&#xff1a;PingCode、Worktile、幕布、腾讯文档、坚果云、Notion中国版、Evernote、SharePoint、Confluence。 在选择知识库管理软件时&#xff0c;面对众多选项是否感到头疼&#xff1f;对于部门内部的协作和知识管理&#xff0c;选择一款适合的工具至…

unity json 处理

1. c#对象 -> json public class Item {public int id;public int num;public Item(int id, int num){this.id id;this.num num;} } public class PlayerInfo {public string name;public int atk;public int def;public float moveSpeed;public double roundSpeed;publi…

域名注册查询方法

域名不仅是网站的地址标识&#xff0c;更是企业和个人在互联网上的身份证明。要确保自己的在线品牌安全&#xff0c;了解域名注册查询方法至关重要。本文将介绍几种常见的域名查询方式&#xff0c;帮助您轻松了解网络资产的归属。 1. WHOIS查询&#xff1a; WHOIS&#xff08;…

一站式数仓解决方案:ECharts+Luckysheet+DataX+Doris打造全能式数据中台

数据中台这个词出现的概率非常高&#xff0c;对于一个企业来讲&#xff0c;那么数据中台是什么呢&#xff1f;数据中台就是把数据从各个系统 用数据库对接、API对接、或者文件上传的形式把数据收集起来&#xff0c;整合加工&#xff0c;最后生成分析的结果&#xff0c;这个结果…

上周稼先社区的活动

参天是什么&#xff1f; 最近”参天”很火&#xff0c;不仅MySQL社区&#xff0c;听说Monty最近也跟他们搞了很多活动。其实说起华为的数据库&#xff0c;只有从事数据库行业的人才知道高斯&#xff0c;其他很多人不知道。但是即使从事数据库相关的人&#xff0c;对另外一个产…

C语言04--数组超详解

1.基本概念 逻辑&#xff1a;一次性定义多个相同类型的变量&#xff0c;并存储到一片连续的内存中语法&#xff1a; 数据类型 数组名字 [ 数据的量 ] ; 示例&#xff1a; int a[5]; int Num ; 语法释义&#xff1a; a 是数组名&#xff0c;即这片连续内存的名称[5] …

【Linux学习】Linux开发工具——vim

&#x1f525;个人主页&#xff1a; Forcible Bug Maker &#x1f525;专栏&#xff1a;Linux学习 目录 &#x1f308;前言&#x1f525;vim的基本概念&#x1f525;vim的基本操作&#x1f525;vim命令模式的命令集&#x1f525;简单vim配置⭐一键配置美观的vim安装方法卸载方…

秒懂Linux之文件

目录 前言 一. C文件接口 二. 文件系统调用接口 open接口​编辑 文件fd的分配规则 利用规则实现重定向 前言 在我们学习文件之前得先明白文件是什么&#xff1f; ——文件 内容 属性—— 文件是谁打开的呢&#xff1f; ——文件由进程调度打开&#xff0c;当然前提是文件…

keepalived保活nginx1,nginx2

1 下载两个小玩意 yum -y install keepalived yum install psmisc -y 2 配置nginx1&#xff0c;2自启脚本 vim /root/shell/check-nginx.sh 我的脚本放在root/shell里 #!/bin/bash #获取nginx正在运行的进程数 npsnumps -C nginx --no-header | wc -lif [ $n…

Unity AB包

AB包比对文件内容: ab包名 包大小 包内容md5字符串 编辑器功能-设置默认资源: 可以选择资源作为默认资源保存到StreamingAssets文件夹并且为他们生成资源对比文件1. 在Unity菜单中添加一个功能按钮触发该功能(MenuItem特性)2. 获取在Project窗口选择的资源信息(Selection类)3. …

【js引擎】如何使用 quickjs 把一个 js 值转换成 c 字符串

开发 js 运行时时&#xff0c;最重要的模块莫过于 console.log 了。有了它&#xff0c;才可以在 js 代码中打印日志。那么如何用 quickjs 引擎实现该模块呢&#xff1f; 实际上 quickjs 已经实现了一个 console 的模块 js_print 实现 其中使用了接口 str JS_ToCStringLen(c…

【Linux】Linux(centos7)安装jdk1.8

第一步&#xff1a;卸载系统自带的JDK rpm -qa|grep java # xxx yyy zzz为你要卸载的插件&#xff0c;插件之间以空格隔开 rpm -e --nodeps xxx yyy zzz 先卸载JDK 第二步&#xff1a;安装JDK1.8 安装JDK rpm -ivh jdk-8u172-linux-x64.rpm 第三步&#xff1a;查看是否安…

基于x86 平台opencv的图像采集和seetaface6的人脸检测功能

目录 一、概述二、环境要求2.1 硬件环境2.2 软件环境三、开发流程3.1 编写测试3.2 配置资源文件3.2 验证功能一、概述 本文档是针对x86 平台opencv的图像采集和seetaface6的人脸检测功能,opencv通过摄像头采集视频图像,将采集的视频图像送给seetaface6的人脸检测模块从而实现…