# 一、模板匹配函数中文说明
安装cv2:

pip install opencv-python

1、目标匹配函数:

cv2.matchTemplate(image, templ, method, result=None, mask=None)

image:待搜索图像
templ:模板图像
result:匹配结果
method:计算匹配程度的方法

2、匹配方法

关于匹配方法,使用不同的方法产生的结果的意义可能不太一样,有些返回的值越大表示匹配程度越好,而有些方法返回的值越小表示匹配程度越好。

关于参数 method:
CV_TM_SQDIFF 平方差匹配法:该方法采用平方差来进行匹配;最好的匹配值为0;匹配越差,匹配值越大。
CV_TM_CCORR 相关匹配法:该方法采用乘法操作;数值越大表明匹配程度越好。
CV_TM_CCOEFF 相关系数匹配法:1表示完美的匹配;-1表示最差的匹配。
CV_TM_SQDIFF_NORMED 归一化平方差匹配法 

CV_TM_CCORR_NORMED 归一化相关匹配法      

CV_TM_CCOEFF_NORMED 归一化相关系数匹配法

3、通过cvMinMaxLoc获取最后的最佳匹配结果

二、python_opencv中cv2.minMaxLoc()函数的使用

cv2.minMaxLoc(src, mask=None)

src是一个矩阵。

函数功能:假设有一个矩阵a,现在需要求这个矩阵的最小值,最大值,并得到最大值,最小值的索引。咋一看感觉很复杂,但使用这个cv2.minMaxLoc()函数就可全部解决。函数返回的四个值就是上述所要得到的。

具体看个例子:

import numpy as np
import cv2
a=np.array([[2,3,4,5],[5,67,8,9],[1,3,4,5]])
print(a)
min_val,max_val,min_indx,max_indx=cv2.minMaxLoc(a)

print(min_val,max_val,min_indx,max_indx)

输出结果:
[[ 2 3 4 5]
[ 5 67 8 9]
[ 1 3 4 5]]
1.0 67.0 (0, 2) (1, 1)
说明这个矩阵a的最小值为1.0,索引为(0,2),最大值为67.0索引为(1,1)

三、应用到图片匹配中,获取缺口信息:

1、详细版:
import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('img_all.jpg', 0)
img2 = img.copy()
template = cv2.imread('img_splice.png', 0)

# cv2.imshow('messi', img)
# cv2.imshow('face', template)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
w, h = template.shape[::-1]
# All the 6 methods for comparison in a list
# methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',
#            'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']

meth = 'cv2.TM_CCOEFF'
img = img2.copy()
'''
exec可以用来执行储存在字符串货文件中的python语句
例如可以在运行时生成一个包含python代码的字符串
然后使用exec语句执行这些语句
eval语句用来计算存储在字符串中的有效python表达式
'''
method = eval(meth)
# 匹配应用
res = cv2.matchTemplate(img, template, method)
mn_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
# print('mn_val',mn_val)
# print('max_val',max_val)
# print('min_loc',min_loc)
# print('max_loc',max_loc)
# 使用不同的方法,对结果的解释不同

# 方法判断
# if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
#     top_left = min_loc
# else:
#     top_left = max_loc
top_left = max_loc
print('偏移像素',top_left[0])

bottom_right = (top_left[0] + w, top_left[1] + h)
cv2.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('method: ' + meth)
plt.show()

2、我破解验证码需要的简化版

import cv2
img = cv2.imread('img_all.jpg', 0)
img2 = img.copy()
template = cv2.imread('img_splice.png', 0)
w, h = template.shape[::-1]
# methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR','cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']
meth = 'cv2.TM_CCOEFF'
img = img2.copy()
'''
exec可以用来执行储存在字符串货文件中的python语句
例如可以在运行时生成一个包含python代码的字符串
然后使用exec语句执行这些语句
eval语句用来计算存储在字符串中的有效python表达式
'''
method = eval(meth)
# 匹配应用
res = cv2.matchTemplate(img, template, method)
mn_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
top_left = max_loc[0]
print('偏移像素',top_left)

参考博客:
https://blog.csdn.net/jacky_ponder/article/details/69396909
https://blog.csdn.net/qq_29023939/article/details/81023062