使用直方图比较图像的相似度

通过直方图比较两个图像相似度原理及OpenCV实现(C#) 需要注意的是直方图比较图像的相似度时,在计算上未考虑像素的空间位置,如下图,当图像旋转时,计算结果仍然不变;同理在某些极端情况下,有可能两个图像直方图完全一致,但是两个图像完全不相似的情况,因此直方图比较图像相似度仅适合环境和特征物体种类固定的图像比对。如上图测试结果,使用相关性比较方法,相似的图像计算值接近1,不相似的图像计算值接近0。由公式可知相关性比较计算结果越接近1,两个图像越相似。由公式可知,卡方计算结果越接近0,两个图像越相似。由公式知,计算结果越接近0,两个图像越相似。 阅读详情

目的:

  直方图在cv领域到处可见,因为其功能在cv算法的实现中比不可少。Opencv库中也集成了关于直方图的不少函数,比如直方图的计算,均衡,归一化,相似度比较等等。

为了体验这些函数,做了个小实验,功能是:打开摄像头,鼠标选定一个框,框内图像作为标准图像,计算出其直方图并显示出来;然后继续鼠标选定框,该框内的图像的直方

图与标准图像的进行相似度计算,计算结果在终端输出,数值越大表示相似度越大。

  工程环境:opencv2.3.1+vs2010。

 

工程代码:

 

复制代码
  1 // hist_test.cpp : 定义控制台应用程序的入口点。
  2 //
  3 
  4 #include "stdafx.h"
  5 #include <opencv2/core/core.hpp>
  6 #include <opencv2/imgproc/imgproc.hpp>
  7 #include <opencv2/highgui/highgui.hpp>
  8 #include <iostream>
  9 #include <stdio.h>
 10 
 11 using namespace cv;
 12 using namespace std;
 13 
 14 int nFrame_num=0;
 15 bool pause=false;
 16 bool tracking=false;
 17 Rect preselectROI,selectROI;//用于存放手选的矩形
 18 bool comp=true;
 19 
 20 Mat rhist,ghist,bhist;
 21 int channels[]={0,1,2};
 22 //const int histsize[]={256,256,256};
 23 const int histsize[]={16,16,16};
 24 const int histsize1=16;
 25 float rranges[]={0,255};
 26 float granges[]={0,255};
 27 float branges[]={0,255};
 28 float range[]={0,255};
 29 const float *ranges1={range};//这里的ranges就相当于一个双指针了
 30 const float *ranges[]={rranges,granges,branges};//ranges是个双指针,且前面一定要用const,即不可改变常量,提高程序的可读性和稳健性
 31 //const float *ranges[]={{0,255},{0,255},{0,255}};
 32 
 33 void onMouse(int event,int x,int y,int,void *)
 34 {
 35     if(event==CV_EVENT_LBUTTONDOWN)
 36     {
 37         selectROI.x=x;
 38         selectROI.y=y;
 39         tracking=false;
 40     }
 41     else if(event==CV_EVENT_LBUTTONUP)
 42     {
 43         selectROI.width=x-selectROI.x;
 44         selectROI.height=y-selectROI.y;
 45         tracking=true;
 46         comp=true;
 47         nFrame_num++;//选定后才算真正意义上的第一帧
 48         if(nFrame_num>=10)nFrame_num=10;//防止nFrame_num溢出
 49     }
 50 }
 51 
 52 int  main(int argc, const char* argv[])
 53 {
 54     Mat frame,img;
 55     Mat staRoiHist;
 56     MatND RoiHist;
 57     int DRAW_H=400,DRAW_W=400;
 58     Mat draw(DRAW_W,DRAW_H,CV_8UC3,Scalar(0,0,0));//建立一个显示直方图的图片,背景为纯黑色
 59     int DRAW_BIN_W=cvRound(DRAW_W/histsize1);
 60 
 61     /****打开摄像头****/
 62     VideoCapture cam(0);
 63     if(!cam.isOpened())
 64         return -1;
 65 
 66     /****鼠标捕捉****/
 67     namedWindow("camera",1);
 68     namedWindow("rgb_hist",1);
 69     setMouseCallback("camera",onMouse,0);//这里用的是面向对象的思想,只要有鼠标动作就会调用鼠标响应函数
 70 
 71     while(1)
 72     {
 73         if(!pause)//暂停按钮只需控制视频的读取
 74         {        
 75         cam>>frame;
 76         if(frame.empty())
 77             break;//break此处跳出的是while语句,一般是跳出for或while语句,不要理解为跳出if语句
 78         }
 79     /*    if(1==nFrame_num)
 80         {
 81 
 82         }*/
 83         if(tracking)
 84         {
 85             Mat RoiImage(frame,selectROI);
 86 
 87             /*************************************************************************************************************************/
 88             /****                                    calcHist():计算图像块的直方图矩阵                                                ****/
 89             /****calcHist(),第1个参数为原数组区域列表;第二个参数为有计算几个原数组;参数3为需要统计的通道索引数;参数4为操作掩码****/
 90             /****第5个参数为存放目标直方图矩阵;参数6为需要计算的直方图的维数;参数7为每一维的bin的个数;参数8为每一维数值的取值范围****/
 91             /****参数10为每个bin的大小是否相同的标志,默认为1,即bin的大小都相同;参数11为直方图建立时清除内存痕迹标志,默认为0,即清除****/
 92             /*************************************************************************************************************************/
 93             calcHist(&RoiImage,1,channels,Mat(),RoiHist,3,histsize,ranges);//原数组区域RoiImage,1个源,需要统计的通道索引为{0,1,2},
 94                                                                             //目标直方图RoiHist,3维,每一维的bin数histsize,取值范围为
 95                                                                             //ranges,实际上计算出的目标矩阵类似一维矩阵。
 96                                                                             
 97 
 98             /*************************************************************************************************************************/
 99             /****                                normalize():根据某种范数或者数值范围归一化数组                                     ****/
100             /**** normalize(),参数1表示需要归一化的数组;参数2为归一化后的目的数组;参数3表示输出数值的最小值/最大值或者输出数值的范数;****/
101             /****  参数4表示输出数值的最小值/最大值;参数5表示归一化数组使用的归一化类型,默认值为使用L2范数;参数6为对应元素的掩膜矩阵 ****/
102             /****                                              默认值为空,即不采用掩膜操作                                            ****/
103             /*************************************************************************************************************************/
104             normalize(RoiHist,RoiHist);//使用L2范数将RoiHist直方图原地归一化
105 
106             vector<Mat> rgb_planes;//这里的vector为向量,向量的数据类型为Mat结构体,向量的长度为3
107             split(RoiImage,rgb_planes);//将rgb图分解到rgb_planes各个分量中
108             calcHist(&rgb_planes[0],1,0,Mat(),rhist,1,&histsize1,&ranges1);
109             normalize(rhist,rhist,0,DRAW_H,NORM_MINMAX);//进行最大最小值归一化
110             calcHist(&rgb_planes[1],1,0,Mat(),ghist,1,&histsize1,&ranges1);
111             normalize(ghist,ghist,0,DRAW_H,NORM_MINMAX);
112             calcHist(&rgb_planes[2],1,0,Mat(),bhist,1,&histsize1,&ranges1);
113             normalize(bhist,bhist,0,DRAW_H,NORM_MINMAX);
114             if(nFrame_num==1)
115             {
116 //                preselectROI=selectROI;
117                 preselectROI.x=selectROI.x;
118                 preselectROI.y=selectROI.y;
119                 preselectROI.width=selectROI.width;
120                 preselectROI.height=selectROI.height;
121                 staRoiHist=RoiHist.clone();//第一次选定目标,作为标准模板目标
122             }
123             else if(nFrame_num>1&&comp==true)
124             {
125                 /*************************************************************************************************************************/
126                 /****                                        compareHist():比较2个直方图的相似度                                         ****/
127                 /****        compareHist(),参数1为比较相似度的直方图1;参数2为比较相似度的直方图2;参数3为相似度的计算方式。有四种,         ****/
128                 /****                  分别为CV_COMP_CORREL,CV_COMP_CHISQR,CV_COMP_INTERSECT,CV_COMP_BHATTACHARYYA                     ****/
129                 /*************************************************************************************************************************/
130                 double distence=compareHist(staRoiHist,RoiHist,CV_COMP_INTERSECT);//计算后面选定的与这次选定的相似度,使用INTERSECT,值越大越相似
131                 printf("与第1次选定的图像区域相似度为:%f\n",distence);//数组越大,相似度越大
132 
133                 //显示直方图
134                 for(int i=1;i<histsize1;i++)
135                 {
136                     //画直线中要注意2点,因为图片的原点在左上角,而直方图坐标系的原点在左下角,所以高度值都需要被直方图图纸高度减掉,另外取一维直方图时只能用at运算符
137                     line(draw,Point(DRAW_BIN_W*(i-1),DRAW_H-cvRound(rhist.at<float>((i-1)))),Point(DRAW_BIN_W*(i),DRAW_H-cvRound(rhist.at<float>(i))),Scalar(255,0,0),2,8,0);
138                     line(draw,Point(DRAW_BIN_W*(i-1),DRAW_H-cvRound(ghist.at<float>((i-1)))),Point(DRAW_BIN_W*(i),DRAW_H-cvRound(ghist.at<float>(i))),Scalar(0,255,0),2,8,0);
139                     line(draw,Point(DRAW_BIN_W*(i-1),DRAW_H-cvRound(bhist.at<float>((i-1)))),Point(DRAW_BIN_W*(i),DRAW_H-cvRound(bhist.at<float>(i))),Scalar(0,0,255),2,8,0);
140                 }
141                 imshow("rgb_hist",draw);
142                 draw=Mat::zeros(DRAW_W,DRAW_H,CV_8UC3);//每画完一次直方图后都进行一次清0操作
143                 comp=false;
144             }
145             rectangle(frame,selectROI,Scalar(0,255,0),2,8);//手动选定一次就显示一次
146         }//end tracking
147         rectangle(frame,preselectROI,Scalar(0,0,255),5,8);//初始的选定目标一直不变
148         imshow("camera",frame);
149 
150         //键盘响应
151         char c = (char)waitKey(10);
152         if( c == 27 )
153             break;
154         switch(c)
155         {
156         case 'p'://暂停键
157             pause = !pause;
158             break;
159         default:
160             ;
161         }
162     }//end while;
163     return 0;
164 }
复制代码

 

 

 

 

实验结果:

  选定框内的模板用红色框标出,其他待比较的模板用绿色框标出。

  模板图像块的简单直方图(rgb分开画的)显示如下:

  

 

   第一次比较结果图:

  

 

  第二次比较结果图:

  

 

   第三次比较结果图(2个框选定的基本重合):

  

 

  三次比较相似度结果:

  

  可以看出,第三次的框与标准框内图像(即第1次选定的图像区域)的相似度值最大。

 

 

图像相似度对比方法 图像相似度计算 阅读详情

相关推荐

OpenCV书签 #直方图算法的原理与相似图片搜索实验

直方图算法(Image Histogram Algorithm)通过统计图像中各个颜色值的分布情况来提供关于图像颜色特征的信息,它可以用来衡量两张图片在颜色分布上的相似度,进而可以用来进行图像相似度的比较,因此,直方图算法是一种常用的图片相似度算法,通常是一个一维的数组(取决于使用通道的数量),其中每个元素表示特定颜色或强度值的像素数量。

有时有味的博客 2643

图像相似度对比-直方图

图像直方图相似度

星空点点 7080

Python图像识别,图片相似度计算!

1.背景 要识别两张图片是否相似,首先我们可能会区分这两张图是人物照,还是风景照等......对应的风景照是蓝天还是大海......做一系列的分类。 从机器学习的的角度来说,首先要提取图片的特征,将这些特征进行分类处理,训练并建立模型,然后在进行识别。 但是让计算机去区分这些图片分别是哪一类是很不容易的,不过计算机可以知道图像的像素值的,因此,在图像识别过程中,通过颜色特征来识别是相似图片是...

Pythoncxy的博客 1万+

图像处理之相似图片识别(直方图应用篇)

图像处理之相似图片识别(直方图应用篇) 算法概述: 首先对源图像与要筛选的图像进行直方图数据采集,对采集的各自图像直方图进行归一化再 使用巴氏系数算法对直方图数据进行计算,最终得出图像相似度值,其值范围在[0, 1]之间 0表示极其不同,1表示极其相似(相同)。 算法步骤详解: 大致可以分为两步,根据源图像与候选图像的像素数据,生成各自直方图数据。第二步:使 用第一步输出的直...

web开发 3891

python opencv比较图片相似度

三直方图算法(Three-Channel Histogram)通常指的是对图像的三个颜色通道(红色、绿色、蓝色)分别计算直方图,并通过比较这些直方图来评估图像的相似度。在OpenCV中,如果你想比较两幅图像的相似度,并且只关心单通道(例如灰度图像)的直方图相似度,你可以计算每幅图像的灰度直方图,并使用直方图比较的方法(如交叉相关、卡方距离、相关性等)来确定相似度。它首先将图像转化为灰度图像,然后计算图像的均值,接着将每个像素的灰度值与均值进行比较,生成一个64位的哈希值。# 计算HSV图像的直方图。

qinshi501的博客 1354

C# 使用 OpenCvSharp 进行直方图比较

接下来,我们将通过具体的示例来展示如何在 C# 中使用 OpenCvSharp 进行直方图比较。跟着我一起,一步步来,你会发现这一切并不难。📋。

java专栏 1865

使用 C++/OpenCV 图像直方图比较两个图片相似度

本文介绍了使用C++和OpenCV进行图像直方图比较的方法。主要内容包括:1) 将图像从BGR转换到HSV色彩空间;2) 计算H-S二维直方图;3) 对直方图进行归一化处理;4) 使用四种不同指标(相关性、卡方、交集和巴氏距离)比较直方图相似度。该技术可用于图像检索和目标识别等领域,代码示例展示了核心实现细节,包括参数设置、函数调用和结果解读。

m0_54069809的博客 1736

基于直方图比较的图像相似度计算

图像相似度计算方法--直方图比较,工程基于vs2005+opencv210实现。下载资源后,如果与自己使用的opencv版本不一致,则需要对工程进行简单配置才能正确运行。

图像采用直方图compare()对比相似度

图像采用直方图compare()对比相似度 #图像采用直方图compare()对比相似度 样式,下面展示同样高亮的 代码片. import cv2 as cv import cv2 import numpy as np import time from matplotlib import pyplot as plt def threshold(image): gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY) ret , binary = cv.threshold(g

weixin_44289316的博客 1194

Apache-Plc4x-Modbus-Tcp学习记录(一)

Apache-Plc4x-Modbus-Tcp学习记录(一)

weixin_45325423的博客 6988

水文模型新手必看:用SWAT-CUP做参数率定,如何正确设置预热期、率定期和验证期?(附数据准备避坑指南)

本文详细介绍了使用SWAT-CUP进行水文模型参数率定的完整流程,重点解析了预热期、率定期和验证期的正确设置方法,并提供了数据准备的避坑指南。通过实操步骤和常见问题解决方案,帮助新手快速掌握SWAT-CUP参数率定的核心技巧,提升水文模型模拟精度。

weixin_26875109的博客 374

Matlab实现两个直方图(histograms )相似性比较

直方图相似性比较 (1)图像相似度比较 如果我们有两张图像,并且这两张图像的直方图一样,或者有极高的相似度,那么在一定程度上,我们可以认为这两幅图是一样的,这就是直方图比较的应用之一。 通过默认的欧氏距离来比较直方图的相似性大小,值越小,两个图像的直方图越相似。 matlab实现: i1 = a; i2 = b; [c1,n]=imhist(i1); c1=c1/size(i1,1)/s...

xiaojianzhao的博客 1万+

SillyTavern角色卡制作全攻略:如何用AI还原你喜欢的虚构角色(附三叶完整角色卡JSON)

本文详细介绍了如何使用SillyTavern制作高质量AI角色卡,以《你的名字》中的宫水三叶为例,从角色特征提取、对话风格捕捉到JSON结构优化,全面解析AI角色扮演的创作技巧。通过具体的写作示例和完整角色卡JSON,帮助二次元爱好者和同人创作者实现虚构角色的精准还原与生动互动。

pandas7gardener的博客 2131

python图片对比相似度_图片的相似度--直方图距离

计算两张图片的相似度直方图距离1.方法描述: 按照某种距离度量的标准对两幅图像的直方图进行相似度的测量。 2.图像直方图丰富的图像细节信息,反映了图像像素点的概率分布情况,统计每一个像素点强度值具有的像素个数。 3.优点:计算量比较小。 4.缺点: 直方图反应的是图像灰度值得概率分布,并没有图像的空间位置信息在里面,因此,会出现误判;比如纹理结构相同,但明暗不同的图像,应该相似度很...

weixin_36353849的博客 2157

STM32F030C8烧录实战:用J-Link Commander实现一键批量烧写(附完整脚本)

本文详细介绍了如何使用J-Link Commander工具链实现STM32F030C8的一键批量烧录,包括环境配置、批处理脚本设计、命令脚本解析以及生产环境实战技巧。通过自动化烧录流程,显著提升效率并降低人为错误,特别适合量产和频繁迭代的开发场景。

weixin_30505225的博客 461

ZYNQ新手必看:5分钟搞定SD卡与QSPI Flash双启动模式配置(附常见问题排查)

本文为ZYNQ开发者提供了SD卡与QSPI Flash双启动模式的完整配置指南与深度排错方法。详细解析了从BootROM、FSBL到BOOT.bin的启动链条,并分步讲解了在Vivado/Vitis中的硬件配置、软件工程创建及BOOT.bin文件生成流程。针对SD卡格式化、文件放置以及QSPI Flash烧录中的常见陷阱(如版本差异、时钟配置)给出了具体解决方案和排查清单,帮助开发者快速实现可靠的产品启动与程序固化。

ll5678的博客 932

Python+OpenCV:全局直方图均衡化、局部直方图自适应均衡化、直方图比较(Python版)

1. 全局直方图均衡化 cv2.equalizeHist(src, dst=None)函数只能处理单通道的数据,src为输入图像对象矩阵,必须为单通道的uint8类型的矩阵数据。直方图均衡化可以看作是图像增强的一个手段,示例代码如下: import cv2 as cv src = cv.imread("D:/Open CV/opencv/sources/samples/data/rice_01....

zjy123078_zjy的博客 1万+

第 5 篇:责任链模式 (Chain of Responsibility) —— 协议栈的流水线

本文介绍了责任链模式在嵌入式通信协议解析中的应用。针对传统"面条式"代码维护困难的问题,提出将各协议解析器解耦为独立处理单元,通过链表形式串联。文章详细展示了模式实现:定义抽象处理者接口、实现具体协议处理器、构建链表管理器。该方案具有内存占用低(O(1)栈空间)、可动态扩展、支持优先级调整等优势,并探讨了性能优化策略及动态插件系统等扩展应用,为嵌入式通信协议处理提供了清晰的架构方案。

一路往蓝-Anbo 的博客 178

opencv之图像直方图的比较(图像的相关度)

(理解直方图比较的意义,对于图像的相似度是非常有意义的) 对于直方图来说,一个不可或缺的工具就是用某些具体的标准来比较两个直方图的相似度要对两个直方图进行比较,首先选择一个衡量直方图相似度的对比标准,我们用compareHist()函数来对比两个直方图的相似度: 对比直方图:compareHist()函数: C++:double compareHist(InputArray h1,InputArr...

nbxuwentao的博客 1113

【机器学习概率统计】11 贝叶斯统计推断:最大后验

这一节,我们来介绍另外一种统计推断方法:贝叶斯统计推断方法。 1.回顾贝叶斯定理 首先,我们先来复习一下贝叶斯定理: p(Θ∣X)=p(X∣Θ)p(Θ)p(X)p(\Theta|X)=\frac{p(X|\Theta)p(\Theta)}{p(X)}p(Θ∣X)=p(X)p(X∣Θ)p(Θ)​ 在这个简简单单的式子当中,蕴含了我们要掌握的很多重要内容: 贝叶斯定理当中的四个概率表达式,他们都非常重要,在这一节的内容中将反复出现,我们来一一解析一下: p(Θ)p(\Theta)p(Θ):先验分布。 反映的是在

机器学习数学基础系列专栏 3271

如何在 Windows 中实时打开字幕

在 Windows 操作系统中,你可以使用编程来实现实时字幕功能,以便在屏幕上显示即时的文字内容。下面是一个示例代码,展示了如何使用Python编程语言在Windows上实现实时字幕功能。这样,字幕窗口将会不断地显示系统当前时间作为字幕。你可以根据自己的需求修改主循环中的内容,以显示你想要的实时字幕。希望以上代码和说明能够帮助你在Windows中实现实时字幕功能。函数创建了一个顶级窗口,并设置窗口的样式、位置和大小。方法,用于在字幕窗口中显示指定的字幕内容。上述代码中,我们使用了Python的。

DevWizard的博客 3270

【python 图片相似度】直方图计算图片相似度

直方图能够描述一幅图像中颜色的全局分布,而且容易理解和实现,所以入门级的图像相似度计算都是使用它的。 直方图算法是对源图像与要筛选的图像进行直方图数据采集,对采集的各自图像直方图进行归一化再使用巴氏系数算法对直方图数据进行计算,最终得出图像相似度值,其值范围在[0, 1]之间0表示极其不同,1表示极其相似(相同)。 算法步骤大致可以分为两步,根据源图像与候选图像的像素数据,生成各自直方图数据。第二...

赖德发的博客 9726

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

直方图比较(图片相关性比较)

直方图比较方法 对输入的两张图像计算得到直方图H1和H2,归一化得到相同的尺度空间然后可以通过计算H1和H2之间的距离得到两个直方图相似程度进而比较图像本身的相似程度。opencv提供的比较方法有四种: Correlation相关性比较(CV_COMP_CORREL)越接近1越相似 Chi-Square卡方比较(CV_COMP_CHISQR)越接近0越相似 Intersection十字交叉性(C...

笔记用 7575

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

java识别图像相似或者包含,图像相似度比较和检测图像中的特定物

对普通人而言,识别任意两张图片是否相似是件很容易的事儿。但是从计算机的角度来识别的话,需要先识别出图像的特征,然后才能进行比对。在图像识别中,颜色特征是最为常见的。每张图像都可以转化成颜色分布直方图,如果两张图片的直方图很接近,就可以认为它们很相似。这有点类似于判断文本的相似程度。图像比较先来比对两张图片,一张是原图另一张是经过直方图均衡化之后的图片。原图和直方图均衡化比较.png二者的相关性因子...

weixin_31001855的博客 1311

Matlab比较2个 二维矩阵 或 二维图像 相似度的方法总结

1、corr2 A = ; B = ; cor = corr2(A,B) 2、通过直方图相似性比较 (参考:https://blog.youkuaiyun.com/xiaojianzhao/article/details/103785809) 如果两张图像的直方图一样,或者有极高的相似度,那么在一定程度上,可以认为这两幅图是一样的,这就是直方图比较的应用之一。通过默认的欧氏距离来比较直方图的相似性大小,值越小,两个图像的直方图越相似。 i1 = a; i2 = b; [c1,n]=imhist(i..

heibaigezi的博客 1万+
上一篇: 方差的统计学应用
下一篇: 这只是一种解释,未必是唯一的解释——人脑处理信息中混入主观歧义
随风而去飘飘飘
博客等级 码龄19年 620粉丝 67原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值