摘要

本文主要总结了进行目标跟踪、检測中常常使用到的图像相似度測量和模板匹配方法,并给出了详细的基于OpenCV的代码实现。

引言

模板匹配是一种在源图像中寻找与图像patch最相似的技术,经常常使用来进行目标的识别、跟踪与检測。当中最相似肯定是基于某种相似度准则来讲的。也就是须要进行相似度的測量。另外,寻找就须要在图像上进行逐行、逐列的patch窗体扫描,当然也不一定须要逐行逐列的扫描。当几个像素的误差比计算速度来的不重要时就能够设置扫描的行列步进值,以加快扫描和计算的时间消耗。以下就对相似度測量和模板匹配进行介绍(全部的图像都假定是灰度图)。

正文

图像相似度測量

直方图方法

方法描写叙述:有两幅图像patch(当然也但是整幅图像),分别计算两幅图像的直方图,并将直方图进行归一化,然后依照某种距离度量的标准进行相似度的測量。

方法的思想:基于简单的向量相似度来对图像相似度进行度量。

长处:直方图可以非常好的归一化,比方256个bin条。那么即使是不同分辨率的图像都可以直接通过其直方图来计算相似度。计算量适中。比較适合描写叙述难以自己主动切割的图像。

缺点:直方图反应的是图像灰度值得概率分布。并没有图像的空间位置信息在里面,因此。经常出现误判。从信息论来讲。通过直方图转换。信息丢失量较大。因此单一的通过直方图进行匹配显得有点力不从心。

基于opencv的实现,我把它封装为函数(输入输出都是灰度图像,且设定的灰度级为8,及0-255),有须要的能够直接拿去使用

<span style="font-size:18px;"><span style="font-size:18px;">double getHistSimilarity(const Mat& I1, const Mat& I2)
{int histSize = 256;float range[] = {0,256};const float* histRange = {range};bool uniform = true;bool accumulate = false;Mat hist1,hist2;calcHist(&I1,1,0,Mat(),hist1,1,&histSize,&histRange,uniform,accumulate);normalize(hist1,hist1,0,1,NORM_MINMAX,-1,Mat());calcHist(&I2,1,0,Mat(),hist2,1,&histSize,&histRange,uniform,accumulate);normalize(hist2,hist2,0,1,NORM_MINMAX,-1,Mat());return compareHist(hist1, hist2, CV_COMP_CORREL);}</span></span>

当中直方图比較的方法在opencv中的实现的有:

/* Histogram comparison methods */
enum
{
    CV_COMP_CORREL        =0,
    CV_COMP_CHISQR        =1,
    CV_COMP_INTERSECT     =2,
    CV_COMP_BHATTACHARYYA =3,
    CV_COMP_HELLINGER     =CV_COMP_BHATTACHARYYA
};
各自是:相关度。卡方,相交系数和巴氏距离。其计算公式例如以下图所看到的:

直方图方法的一些改进的出发点大致是为了改善直方图无法利用空间位置信息的弱点,比方FragTrack算法,将图像再进行切割成横纵的patch,然后对于每个patch搜索与之匹配的直方图,来计算两幅图像的相似度,从而融入了直方图相应的位置信息,但计算效率肯定不高。

矩阵分解的方法

方法描写叙述:将图像patch做矩阵分解,比方SVD神秘值分解和NMF非负矩阵分解等,然后再做相似度的计算。

方法思想:由于图像本身来讲就是一个矩阵,能够依靠矩阵分解获取一些更加鲁棒的特征来对图像进行相似度的计算。

基于SVD分解的方法长处:神秘值的稳定性,比例不变性。旋转不变性和压缩性。

即神秘值分解是基于总体的表示。不但具有正交变换、旋转、位移、镜像映射等代数和几何上的不变性,并且具有良好的稳定性和抗噪性,广泛应用于模式识别与图像分析中。对图像进行神秘值分解的目的是得到唯一、稳定的特征描写叙述。减少特征空间的维度,提高抗干扰能力。

基于SVD分解的方法缺点是:神秘值分解得到的神秘矢量中有负数存在,不能非常好的解释其物理意义。

基于NMF分解的方法:将非负矩阵分解为能够体现图像主要信息的基矩阵与系数矩阵。而且能够对基矩阵赋予非常好的解释,比方对人脸的切割,得到的基向量就是人的“眼睛”、“鼻子”等主要概念特征,源图像表示为基矩阵的加权组合,所以。NMF在人脸识别场合发挥着巨大的作用。
基于矩阵特征值计算的方法还有非常多,比方Trace变换,不变矩计算等。

基于特征点方法

方法描写叙述:统计两个图像patch中匹配的特征点数。假设相似的特征点数比例最大,则觉得最相似,最匹配
方法思想:图像能够中特征点来描写叙述,比方sift特征点。LK光流法中的角点等等。

这样相似度的測量就转变为特征点的匹配了。

曾经做过一些实验。关于特征点匹配的。对一幅图像进行仿射变换,然后匹配两者之间的特征点。选取的特征点有sift和高速的sift变形版本号surf等。
方法长处:能被选作特征点的大致要满足不变性,尺度不变性,旋转不变等。这样图像的相似度计算也就具备了这些不变性。
方法缺点:特征点的匹配计算速度比較慢。同一时候特征点也有可能出现错误匹配的现象。

基于峰值信噪比(PSNR)的方法

当我们想检查压缩视频带来的细微差异的时候,就须要构建一个可以逐帧比較差视频差异的系统。最
经常使用的比較算法是PSNR( Peak signal-to-noise ratio)。这是个使用“局部均值误差”来推断差异的最简单的方法。如果有这两幅图像:I1和I2,它们的行列数各自是i。j。有c个通道。

每一个像素的每一个通道的值占用一个字节。值域[0,255]。

注意当两幅图像的同样的话。MSE的值会变成0。这样会导致PSNR的公式会除以0而变得没有意义。所以我们须要单独的处理这种特殊情况。此外因为像素的动态范围非常广,在处理时会使用对数变换来缩小范围。

基于OpenCV的PSNR方法实现,相同将其封装为函数,能够直接拿来调用:

<span style="font-size:18px;">double getPSNR(const Mat& I1, const Mat& I2)
{Mat s1;absdiff(I1, I2, s1);       // |I1 - I2|s1.convertTo(s1, CV_32F);  // cannot make a square on 8 bitss1 = s1.mul(s1);           // |I1 - I2|^2Scalar s = sum(s1);         // sum elements per channeldouble sse = s.val[0] + s.val[1] + s.val[2]; // sum channelsif( sse <= 1e-10) // for small values return zeroreturn 0;else{double  mse =sse /(double)(I1.channels() * I1.total());double psnr = 10.0*log10((255*255)/mse);return psnr;}
}</span>

在考察压缩后的视频时,这个值大约在30到50之间。数字越大则表明压缩质量越好。假设图像差异非常明显,就可能会得到15甚至更低的值。PSNR算法简单,检查的速度也非常快。

可是其呈现的差异值有时候和人的主观感受不成比例。所以有第二种称作 结构相似性 的算法做出了这方面的改进。

基于结构相似性(SSIM,structural similarity (SSIM) index measurement)的方法

结构相似性理论觉得,自然图像信号是高度结构化的,即像素间有非常强的相关性。特别是空域中最接近的像素。这样的相关性蕴含着视觉场景中物体结构的重要信息;HVS的主要功能是从视野中提取结构信息,能够用对结构信息的度量作为图像感知质量的近似。

结构相似性理论是一种不同于以往模拟HVS低阶的组成结构的全新思想,与基于HVS特性的方法相比,最大的差别是自顶向下与自底向上的差别。

这一新思想的关键是从对感知误差度量到对感知结构失真度量的转变。它没有试图通过累加与心理物理学简单认知模式有关的误差来预计图像质量,而是直接预计两个复杂结构信号的结构改变。从而在某种程度上绕开了自然图像内容复杂性及多通道去相关的问题.作为结构相似性理论的实现。结构相似度指数从图像组成的角度将结构信息定义为独立于亮度、对照度的。反映场景中物体结构的属性。并将失真建模为亮度、对照度和结构三个不同因素的组合。用均值作为亮度的预计。标准差作为对照度的预计,协方差作为结构相似程度的度量。

基于OpenCV的SSIM方法实现。相同将其封装为函数,能够直接拿来调用:

<span style="font-size:18px;">Scalar getMSSIM( const Mat& i1, const Mat& i2)
{const double C1 = 6.5025, C2 = 58.5225;/***************************** INITS **********************************/int d     = CV_32F;Mat I1, I2;i1.convertTo(I1, d);           // cannot calculate on one byte large valuesi2.convertTo(I2, d);Mat I2_2   = I2.mul(I2);        // I2^2Mat I1_2   = I1.mul(I1);        // I1^2Mat I1_I2  = I1.mul(I2);        // I1 * I2/*************************** END INITS **********************************/Mat mu1, mu2;   // PRELIMINARY COMPUTINGGaussianBlur(I1, mu1, Size(11, 11), 1.5);GaussianBlur(I2, mu2, Size(11, 11), 1.5);Mat mu1_2   =   mu1.mul(mu1);Mat mu2_2   =   mu2.mul(mu2);Mat mu1_mu2 =   mu1.mul(mu2);Mat sigma1_2, sigma2_2, sigma12;GaussianBlur(I1_2, sigma1_2, Size(11, 11), 1.5);sigma1_2 -= mu1_2;GaussianBlur(I2_2, sigma2_2, Size(11, 11), 1.5);sigma2_2 -= mu2_2;GaussianBlur(I1_I2, sigma12, Size(11, 11), 1.5);sigma12 -= mu1_mu2;/ FORMULA Mat t1, t2, t3;t1 = 2 * mu1_mu2 + C1;t2 = 2 * sigma12 + C2;t3 = t1.mul(t2);              // t3 = ((2*mu1_mu2 + C1).*(2*sigma12 + C2))t1 = mu1_2 + mu2_2 + C1;t2 = sigma1_2 + sigma2_2 + C2;t1 = t1.mul(t2);               // t1 =((mu1_2 + mu2_2 + C1).*(sigma1_2 + sigma2_2 + C2))Mat ssim_map;divide(t3, t1, ssim_map);      // ssim_map =  t3./t1;Scalar mssim = mean( ssim_map ); // mssim = average of ssim mapreturn mssim;
}
</span>

图像模板匹配

一般而言,源图像与模板图像patch尺寸一样的话,能够直接使用上面介绍的图像相似度測量的方法;假设源图像与模板图像尺寸不一样。通常须要进行滑动匹配窗体,扫面个整幅图像获得最好的匹配patch。

在OpenCV中相应的函数为:matchTemplate():函数功能是在输入图像中滑动窗体寻找各个位置与模板图像patch的相似度。相似度的评价标准(匹配方法)有:CV_TM_SQDIFF平方差匹配法(相似度越高,值越小),CV_TM_CCORR相关匹配法(採用乘法操作,相似度越高值越大),CV_TM_CCOEFF相关系数匹配法(1表示最好的匹配,-1表示最差的匹配)。

CV_TM_SQDIFF计算公式:

CV_TM_CCORR计算公式:

有一种新的用来计算相似度或者进行距离度量的方法:EMD,Earth Mover's Distances

EMD is defined as the minimal cost that must be paid to transform one histograminto the other, where there is a “ground distance” between the basic featuresthat are aggregated into the histogram。

光线变化能引起图像颜色值的漂移,虽然漂移没有改变颜色直方图的形状,但漂移引起了颜色值位置的变化,从而可能导致匹配策略失效。而EMD是一种度量准则,度量如何将一个直方图转变为还有一个直方图的形状,包含移动直方图的部分(或所有)到一个新的位置,能够在随意维度的直方图上进行这样的度量。

在OpenCV中有对应的计算方法:cvCalcEMD2()。

结合着opencv支持库。计算直方图均衡后与原图的HSV颜色空间直方图之间的EMD距离。

*******************************************************************************************************************************************************************************************************

2015-7-24

图像类似度測量与模板匹配总结相关推荐

  1. 一种基于模板匹配的图像配准方法

    01 前言 如下图所示,有时候参考图像与浮动图像的灰度区别很大,但是它们又有某一个小区域比较相似,这种情况下直接通过特征点匹配或形变优化来配准的效果并不理想. 这个时候我们可以尝试使用模板匹配的方法来 ...

  2. 使用多模板匹配进行DICOM图像的自动勾画

    提纲 目的 什么是模板匹配 什么是自动勾画 如何进行基于多模板匹配的自动勾画 目的 放射治疗是治疗恶性肿瘤的主要手段之一.其基本原则是最大限度地保证射线剂量全部集中在放疗靶区内(包括GTV.CTV和P ...

  3. 基于模板匹配的目标跟踪法

    基于灰度图像处理的方法是依据图像中灰度模式来实现目标提取.假设运动物体为刚性目标,在 t 时刻(x,y)像素处的灰度值为 (f x,y,t),而 t 时刻参考图像(x,y)像素处的灰度值为 运动目标检 ...

  4. 基于opencv的模板匹配详解

    1.什么是模板匹配 在OpenCV教程中这样解释模板匹配: 模板匹配是一项在一幅图像中寻找与另一幅模板图像最匹配(相似)部分的技术.这里说的模板是我们已知的小图像,模板匹配就是在一副大图像中搜寻目标. ...

  5. OpenCV4学习笔记(19)——模板匹配

    本次要整理记录的内容是:模板匹配. 模板匹配可以说是一种最简单的模式识别方法,它的实现主要是通过模板图像在被匹配图像中的平移,在被匹配图像中逐个区域寻找和模板图像相似的区域,如果存在某区域的相似度大于 ...

  6. OpenCV-Python:模板匹配

    啥叫模板匹配 模板匹配就是在大图中找小图,也就说在一幅图像中寻找另一幅模板图像的位置: OpenCV使用 cv2.matchTemplate() 实现模板匹配. import cv2 import n ...

  7. python模板匹配_OpenCV-Python:模板匹配

    啥叫模板匹配 模板匹配就是在大图中找小图,也就说在一幅图像中寻找另一幅模板图像的位置: OpenCV使用 cv2.matchTemplate() 实现模板匹配. importcv2importnump ...

  8. 图像相似度测量与模板匹配总结

    摘要 本文主要总结了进行目标跟踪.检测中经常使用到的图像相似度测量和模板匹配方法,并给出了具体的基于OpenCV的代码实现. 引言 模板匹配是一种在源图像中寻找与图像patch最相似的技术,常常用来进 ...

  9. 图像相似度测量和模板匹配方法

    摘要 本文主要总结了进行目标跟踪.检测中经常使用到的图像相似度测量和模板匹配方法,并给出了具体的基于OpenCV的代码实现. 引言 模板匹配是一种在源图像中寻找与图像patch最相似的技术,常常用来进 ...

最新文章

  1. C# DataGridView 的UserDeletingRow事件,删除
  2. 2.2 进阶-禁忌雷炎
  3. 音乐、视频播放模式切换实现方案及原理解析(基于vue、vuex、h5 audio)
  4. C++函数名的修饰规则
  5. ZetCode Ruby 教程
  6. 微信小程序_(校园视)开发视频的展示页_上
  7. c语言有2维结构体没,c语言结构体说明
  8. 如何批量修改公式的字体
  9. TurboMail邮件服务器腾云驾务云化邮件办公
  10. 机器学习——HMM(隐马尔可夫模型的基本概念)(一)
  11. Srping事务的传播行为和隔离级别
  12. Http 理论基础-请求与响应、响应状态码汇总
  13. 深度梯度压缩:减小分布式训练的通信带宽
  14. 处理 Vue-Router + Webpack 动态加载的一些小问题
  15. 【NOIP2016普及组复赛模拟赛】买装备(equipment)
  16. C++编程读取注册表文件
  17. 在线小说网站的设计与实现(附源码)
  18. 加权算数平均大于等于几何平均
  19. Java3:数组和字符串
  20. vector函数总结

热门文章

  1. Python md5 sha1 的使用
  2. 合成谬误与公地悲剧(为何设置产品总监职位及核算名义成本)
  3. 第一次加入博客那,鼓励一下自己先
  4. 【Java】关于Java编程软件idea快捷键的使用
  5. 多个 小程序_最简单的小程序制作方法,不会代码也能撸一个
  6. oracle+连接数sessionn,Oracle进程连接数过多时的Statspack分析报告
  7. python3没有decode_我如何在Python3中使用.decode('string-escape')?
  8. 2021想学UI设计,你必需要知道这些
  9. JavaScript面向对象编程理解
  10. oracle number 7 5,oracle上机练习6-7及答案