OpenCV-python 模板匹配cv2.matchTemplate()与cv2.minMaxLoc()
一 模板匹配(Template Matching)原理
1. 什么是模板匹配?
模板匹配是用来在一副大图中搜寻查找模版图像位置的方法。
你有一副原图像,还有一小块模板(很小的图像,有可能来源于原图像),通过模板找出原图中和模板相似的位置。
2. 模板匹配适用场景
除了轮廓滤波处理之外,模板匹配可以说是对象检测的最简单形式之一:- 模板匹配实现简单,只需要2-3行代码
- 模板匹配计算效率高
- 它不需要执行阈值化、边缘检测等操作来生成二值化图像(而轮廓检测处理需要)
- 通过简单扩展,模板匹配可以检测输入图像中相同或者相似对象的多个实例
如果你的输入图像中包含这些类型的变化因素,则你不应使用模板匹配,而应该使用专用的对象检测器,包括 HOG + 线性 SVM;Faster R-CNN;SSD;YOLO 等。
但是,在旋转、缩放和视角恒定的情况下,模板匹配可以完美地发挥作用。
3. 如何实现模板匹配?
OpenCV 为我们提供了函数: cv2.matchTemplate()用于实现模板匹配,并使用cv2.minMaxLoc()计算匹配结果。
void cv::matchTemplate ( InputArray image, InputArray templ, OutputArray result, int method, InputArray mask = noArray() )
result = cv.matchTemplate( image, templ, method[, result[, mask]] )
参数:
- image: 待搜索的原图;
- templ:模板图像;
- result:匹配的结果;
- method:进行匹配的方法;
- mask:掩膜;如果您只想检测模板图像上的特定区域,则可以为模板图像提供一个掩膜;掩膜,即为模板图像上感兴趣的区域,用于忽略模板图像上无用的干扰的特征,即不属于检测目标的干扰特征。对于模板上你不希望被搜索的区域,掩膜值应该设置为0。对于模板图像上您要进行搜索的区域,掩膜值应该设置为255。掩膜与模板图像具有相同的维度,并且每个元素的类型也需要一致。
返回值:
result:
minVal, maxVal, minLoc, maxLoc = cv.minMaxLoc( src[, mask] )
参数:
src就是cv2.matchTemplate()返回的矩阵result;
返回值:
minVal:最小值;
maxVal:最大值;
minIdx:最小值对应图像的位置;
maxIdx:最大值对应图像的位置;
和 2D 卷积一样,模板匹配也是用模板图像在输入图像(大图)上滑动,并在每一个位置对模板图像和与其对应的输入图像的子区域进行比较。
OpenCV提供了几种不同的比较方法(细节请看文档)。
返回的结果是一个灰度图像,每一个像素值表示了此区域与模板的匹配程度。
如果输入图像的大小是(WxH),模板的大小是(wxh),输出的结果的大小就是(W-w+1, H-h+1)。
当你得到这幅图之后,就可以使用函数 cv2.minMaxLoc() 来找到其中的最小值和最大值的位置。
第一个值为矩形左上角的点(x, y),(w, h)为 模板矩形的宽和高。这个矩形就是找到的模板区域了。
二 模板匹配的方法
1. 模板匹配支持的方法
模板匹配的方法,参数method支持以下几种:
enum cv::TemplateMatchModes { cv::TM_SQDIFF = 0, cv::TM_SQDIFF_NORMED = 1, cv::TM_CCORR = 2, cv::TM_CCORR_NORMED = 3, cv::TM_CCOEFF = 4, cv::TM_CCOEFF_NORMED = 5 }
method | 含义 |
CV_TM_SQDIFF | 平方差匹配法:该方法用平方差来进行匹配;最好的匹配为0;匹配越差,匹配值越大。 |
CV_TM_CCORR | 相关匹配法:该方法采用乘法操作;数值越大表名匹配程度越好。 |
CV_TM_CCOEFF | 相关系数匹配法:1表示完美匹配;-1表示最差匹配。 |
CV_TM_SQDIFF_NORMED | 归一化平方差匹配法:计算归一化平方差,计算出来的值越接近0,越相关。 |
CV_TM_CCORR_NORMED | 归一化相关匹配法:计算归一化相关性,计算出来的值越接近1,越相关。 |
CV_TM_CCOEFF_NORMED | 归一化相关系数匹配法:计算归一化相关系数,计算出来的值越接近1,越相关。 |
2. 如何选用模板方法
通常情况是:如果想要精确或接近精确的匹配,请使SSD。它较快,而且肯定按照你所要求的那样,试图最小化模板图片和目标图像之间的差异。在这种情况下,是不需要归一化的,那只是徒增开销。
另一种情况是,如果需要多个模板来进行比较,那么建议将SSD算法归一化。
还有一种情况是,如果你使用的是,可能有曝光或对比度差异的真实照片,那么ZNCC(Zero-normalized cross-correlation)所包含的均值漂移和方差均衡可能会带来最好的结果。
各模板方法比较:
2.1 TM_CCORR
互相关算法(cross-correlation)是一种经典的统计匹配算法,通过计算模板图像和匹配图像的互相关程度
,来确定匹配的程度。互相关程度
最大时的搜索窗口位置决定了模板图像在待匹配图像中的位置。
特点:
擅长区分出(有颜色差异的)不同区域。
2.2 TM_SQDIFF
误差平方和算法(Sum of Squared Differences,简称SSD算法),也叫差方和算法。
优点:
思路简单,容易理解(子图与模板图对应位置上,灰度值之差的绝对值总和,再求平均)。
运算过程简单,匹配精度高。
缺点:
运算量偏大。对噪声非常敏感。
2.3 TM_CCOEFF
是互相关算法(cross correlation)和均值漂移算法的结合。
优点:
算法计算量小,简单易实现,很适合于实时跟踪场合
缺点:
跟踪小目标和快速移动目标时常常失败,而且在全部遮挡情况下不能自我恢复跟踪。
2.4 TM_CCORR_NORMED
归一化互相关(Normalized Cross Correlation method, NCC)匹配算法。
它是一个亮度、对比度线性不变量。此算法的缺点是参与运算的特征点比较多,运算速度比较慢。