摘要

本文主要总结了进行目标跟踪、检测中经常使用到的图像相似度测量和模板匹配方法,并给出了具体的基于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

转载于:https://www.cnblogs.com/huty/p/8519295.html

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

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

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

  2. opencv基础--图像模板匹配

    参考:https://blog.csdn.net/ivanhawking/article/details/83182692(该链接附载链接有处理多目标,旋转,缩放等匹配的方法) 1.概述 图像匹配是指 ...

  3. OpenCV 进行图像相似度对比的几种办法-【顺带附py对比学习案例】

    最近研究了下计算机视觉.图像对比参考了一下py的一些源码和思路等信息学习学习. 但是呢只能对应相似度.稍微改一改剪切了图片后的就变化差异比较大,对目前自己的需求来说不是很有作用,顺带整理分享一下. 如 ...

  4. 进行图像相似度对比的几种办法

    转载自 1.直方图方法 方法描述:有两幅图像patch(当然也可是整幅图像),分别计算两幅图像的直方图,并将直方图进行归一化,然后按照某种距离度量的标准进行相似度的测量. 方法的思想:基于简单的向量相 ...

  5. OpenCV中的模板匹配/Filter2d

    1.模板匹配 模板匹配是在图像中寻找目标的方法之一.Come On, Boy.我们一起来看看模板匹配到底是怎么回事. 参考链接:http://www.opencv.org.cn/opencvdoc/2 ...

  6. 通过模板匹配先定位检测的对象再检测圆形零件和孔针02

    图中红色区域的孔和针的检测 如果相机像素很大,直接找很慢,可以通过深度学习的方式或模板匹配定位,然后再做检测 1 images/HoleTemplate.jpg  NeedleTemplate.jpg ...

  7. OpenMV4 H7 PLUS摄像头模板匹配

    使用OpenMV4 H7 PLUS摄像头进行矩形.三角形.圆三种形状的模板匹配: 参考: 官网:https://book.openmv.cc 函数库:https://docs.singtown.com ...

  8. 基于形状的模板匹配(用于字符识别)研究

    一.各模板匹配方法对比 1.基于灰度的匹配一般被称为模版匹配,直接以灰度进行匹配效果不好,对光照很敏感,所以一般会以灰度归一化互相关(NCC)作为匹配依据,增强光照变化下的鲁棒性,为了降低计算量,多采 ...

  9. OpenCV-Python教程:模板匹配(matchTemplate)

    原文链接:http://www.juzicode.com/opencv-python-matchtemplate 返回Opencv-Python教程 模板匹配可以实现在源图像中查找特征图像,特征图像一 ...

最新文章

  1. vs 添加ico图 到资源
  2. YOLO-6D论文的一些相关知识
  3. 在geth客户端调用已部署的智能合约
  4. 图解面向对象中的聚合与耦合概念
  5. 拷贝的代码中去除行号的方法
  6. 【Linux】基础知识
  7. 移动推送消息送达常见问题与解决办法
  8. jQuery EasyUI使用教程之创建展开行详细编辑表单的CRUD应用
  9. 9个开源自动化测试框架,质量保证测试工程师用起来
  10. NPM 常用命令和参数的意思
  11. supesite 更换目录或者域名操作方法
  12. vector容器——赋值操作
  13. racecar 尝试记录
  14. 苏宁易购启动2022年货节:双线上线千场直播,拉满过年氛围
  15. matlab 康托尔集,【德国数学康托尔构造的这个图形叫分形,称做康托尔集.从长度为1的...-康托尔-谭榷刨同学...
  16. Window7使用虚拟桌面
  17. 计算机用户授权原则,涉密信息系统严格设定用户权限,按照什么密级防护和什么授权管理的原则...
  18. 《每日论文》ImageNet Classification with Deep Convolutional Neural Networks
  19. Excel怎么设置每页都打印标题行?
  20. 斗地主自动出牌函数c语言,斗地主AI出牌(示例代码)

热门文章

  1. Windows在当前目录快速打开cmd的方法
  2. cpu的基本硬件组成
  3. php中url编码地址栏,php url地址栏传中文乱码解决方法集合_PHP
  4. 【规范】流程图的标准画法
  5. 中值滤波讲解-Matlab
  6. java.sql.SQLException: Before start of result set ---错误笔记
  7. 字节、半字、字对齐方式
  8. 安装rime中文输入法
  9. python(numpy,pandas11)——pandas merge根据索引合并数据
  10. python中format的用法菜鸟教程-初学者必知的Python中优雅的用法