热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

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

目的:

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

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

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

  工程环境:opencv2.3.1+vs2010。

 

工程代码:

 

  1 // hist_test.cpp : 定义控制台应用程序的入口点。
2 //
3
4 #include "stdafx.h"
5 #include
6 #include
7 #include
8 #include
9 #include
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.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 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.与第1次选定的图像区域相似度为:%f\n",distence);//数组越大,相似度越大
132
133 //显示直方图
134 for(int i=1;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次选定的图像区域)的相似度值最大。

 

 


推荐阅读
  • 颜色迁移(reinhard VS welsh)
    不要谈什么天分,运气,你需要的是一个截稿日,以及一个不交稿就能打爆你狗头的人,然后你就会被自己的才华吓到。------ ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • Html5-Canvas实现简易的抽奖转盘效果
    本文介绍了如何使用Html5和Canvas标签来实现简易的抽奖转盘效果,同时使用了jQueryRotate.js旋转插件。文章中给出了主要的html和css代码,并展示了实现的基本效果。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • 基于dlib的人脸68特征点提取(眨眼张嘴检测)python版本
    文章目录引言开发环境和库流程设计张嘴和闭眼的检测引言(1)利用Dlib官方训练好的模型“shape_predictor_68_face_landmarks.dat”进行68个点标定 ... [详细]
  • 十大经典排序算法动图演示+Python实现
    本文介绍了十大经典排序算法的原理、演示和Python实现。排序算法分为内部排序和外部排序,常见的内部排序算法有插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。文章还解释了时间复杂度和稳定性的概念,并提供了相关的名词解释。 ... [详细]
  • 超级简单加解密工具的方案和功能
    本文介绍了一个超级简单的加解密工具的方案和功能。该工具可以读取文件头,并根据特定长度进行加密,加密后将加密部分写入源文件。同时,该工具也支持解密操作。加密和解密过程是可逆的。本文还提到了一些相关的功能和使用方法,并给出了Python代码示例。 ... [详细]
  • Ihaveaworkfolderdirectory.我有一个工作文件夹目录。holderDir.glob(*)>holder[ProjectOne, ... [详细]
  • 本文介绍了一个Python函数same_set,用于判断两个相等长度的数组是否包含相同的元素。函数会忽略元素的顺序和重复次数,如果两个数组包含相同的元素,则返回1,否则返回0。文章还提供了函数的具体实现代码和样例输入输出。 ... [详细]
  • 本文介绍了Foundation框架中一些常用的结构体和类,包括表示范围作用的NSRange结构体的创建方式,处理几何图形的数据类型NSPoint和NSSize,以及由点和大小复合而成的矩形数据类型NSRect。同时还介绍了创建这些数据类型的方法,以及字符串类NSString的使用方法。 ... [详细]
  • 本文介绍了利用ARMA模型对平稳非白噪声序列进行建模的步骤及代码实现。首先对观察值序列进行样本自相关系数和样本偏自相关系数的计算,然后根据这些系数的性质选择适当的ARMA模型进行拟合,并估计模型中的位置参数。接着进行模型的有效性检验,如果不通过则重新选择模型再拟合,如果通过则进行模型优化。最后利用拟合模型预测序列的未来走势。文章还介绍了绘制时序图、平稳性检验、白噪声检验、确定ARMA阶数和预测未来走势的代码实现。 ... [详细]
  • 正则表达式及其范例
    为什么80%的码农都做不了架构师?一、前言部分控制台输入的字符串,编译成java字符串之后才送进内存,比如控制台打\, ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • Python使用Pillow包生成验证码图片的方法
    本文介绍了使用Python中的Pillow包生成验证码图片的方法。通过随机生成数字和符号,并添加干扰象素,生成一幅验证码图片。需要配置好Python环境,并安装Pillow库。代码实现包括导入Pillow包和随机模块,定义随机生成字母、数字和字体颜色的函数。 ... [详细]
author-avatar
Tibetan-妍自_557
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有