【opencv】template matching 模板匹配 之 模板选择
前言
opencv提供了6种模板匹配的算法:
原算法 | 归一化后的算法 |
---|---|
cv.TM_CCOEFF | cv.TM_CCOEFF_NORMED |
cv.TM_CCORR | cv.TM_CCORR_NORMED |
cv.TM_SQDIFF | cv.TM_SQDIFF_NORMED |
以下介绍 选择思路 与 各种算法的特点
选用指引
I think it really depends on your imagery and template. Generally I’d say: if you’re looking for exact or very close to exact matches, use SSD. It is fast, and it definitely maps to what you’re trying to minimize (the difference between the template and image patch). There’s no need to normalize in that case, it is just added overhead. If you have similar requirements but need multiple templates to be comparable, then normalize the SSD. If you’re looking for matches, but you’re working with real-world photographs that may have exposure or contrast differences, the mean shifting and variance equalization from ZNCC will likely be the best.
我认为这取决于你的图像和模板。
通常情况是:如果想要精确或接近精确的匹配,请使SSD
。它较快,而且肯定按照你所要求的那样,试图最小化模板图片和目标图像之间的差异。在这种情况下,是不需要归一化的,那只是徒增开销。
另一种情况是,如果需要多个模板来进行比较,那么建议将SSD
算法归一化
。
还有一种情况是,如果你使用的是,可能有曝光或对比度差异的真实照片,那么ZNCC
(译者注:这里的ZNCC
指的是Zero-normalized cross-correlation
)所包含的均值漂移和方差均衡可能会带来最好的结果。
(摘自https://stackoverflow.com/questions/58158129/understanding-and-evaluating-template-matching-methods)
一. opencv算法分析
(文末附有各算法的拓展阅读)
1. TM_CCORR
**互相关算法**(cross-correlation)是一种经典的统计匹配算法,通过计算模板图像和匹配图像的互相关程度
,来确定匹配的程度。互相关程度
最大时的搜索窗口位置决定了模板图像在待匹配图像中的位置。
特点
擅长区分出(有颜色差异的)不同区域。
2. TM_SQDIFF
误差平方和算法(Sum of Squared Differences,简称SSD算法),也叫差方和算法
优点
- 思路简单,容易理解(子图与模板图对应位置上,灰度值之差的绝对值总和,再求平均)。
- 运算过程简单,匹配精度高。
缺点
- 运算量偏大。
- 对噪声非常敏感。
3. TM_CCOEFF
(没查到相关翻译,或可译为)均值漂移的互相关算法(Mean shifted cross correlation [Pearson correlation coefficient])。是互相关算法
(cross correlation)和均值漂移算法的结合。
均值漂移算法:
均值漂移算法是一种基于密度梯度上升的非参数方法,通过迭代运算找到目标位置,实现目标跟踪。
(摘自百度百科)
优点
算法计算量小,简单易实现,很适合于实时跟踪场合
缺点
跟踪小目标和快速移动目标时常常失败,而且在全部遮挡情况下不能自我恢复跟踪
4. TM_CCORR_NORMED
归一化互相关(Normalized Cross Correlation method, NCC)匹配算法。
它是一个亮度、对比度线性不变量。
此算法的缺点是参与运算的特征点比较多,运算速度比较慢。
4. 其他归一化算法
另外两种算法是TM_SQDIFF_NORMED
和 TM_CCOEFF_NORMED
。这里暂不单独介绍。
什么时候应该使用归一化?
(推荐阅读:特征工程中的「归一化」有什么作用? - 知乎)
这里摘抄一下上文的结论:
如果对输出结果范围有要求,用归一化
如果数据较为稳定,不存在极端的最大最小值,用归一化
如果数据存在异常值和较多噪音,用标准化,可以间接通过中心化避免异常值和极端值的影响
(摘自特征工程中的「归一化」有什么作用? - 知乎)
附录:图像匹配中的常用算法总结
- 平均绝对差算法(Mean Absolute Differences,简称MAD算法)
- 绝对误差和算法(Sum of Absolute Differences,简称SAD算法)
- 误差平方和算法(Sum of Squared Differences,简称SSD算法),也叫差方和算法
- 平均误差平方和算法(Mean Square Differences,简称MSD算法),也称均方差算法(MSD之于SSD,等同于MAD之于SAD)
- 归一化积相关算法(Normalized Cross Correlation,简称NCC算法),利用子图与模板图的灰度,通过归一化的相关性度量公式来计算二者之间的匹配程度。
- 序贯相似性检测算法(Sequential Similiarity Detection Algorithm,简称SSDA算法),是对传统模板匹配算法的改进,比MAD算法快几十到几百倍
二. 官方代码示例
1. 本例中使用的图片
原图
模板图片
2. 代码
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('messi5.jpg',0)
img2 = img.copy()
template = cv.imread('template.jpg',0)
w, h = template.shape[::-1]
# All the 6 methods for comparison in a list
methods = ['cv.TM_CCOEFF', 'cv.TM_CCOEFF_NORMED', 'cv.TM_CCORR',
'cv.TM_CCORR_NORMED', 'cv.TM_SQDIFF', 'cv.TM_SQDIFF_NORMED']
for meth in methods:
img = img2.copy()
method = eval(meth)
# Apply template Matching
res = cv.matchTemplate(img,template,method)
min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res)
# If the method is TM_SQDIFF or TM_SQDIFF_NORMED, take minimum
if method in [cv.TM_SQDIFF, cv.TM_SQDIFF_NORMED]:
top_left = min_loc
else:
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
cv.rectangle(img,top_left, bottom_right, 255, 2)
plt.subplot(121),plt.imshow(res,cmap = 'gray')
plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(img,cmap = 'gray')
plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
plt.suptitle(meth)
plt.show()
3. 结果
1. cv.TM_CCOEFF
3. cv.TM_CCORR
4. 简评
可以看出, cv.TM_CCORR在这个场景中表现不太好
参考链接
Understanding and evaluating template matching methods - stackoverflow
Lecture 7: Correspondence Matching - 宾夕法尼亚州立大学
卷积(convolution)与互相关(cross-correlation)的一点探讨 - 知乎
【图像配准】基于灰度的模板匹配算法(一):MAD、SAD、SSD、MSD、NCC、SSDA、SATD算法 - CSDN