OpenCV学习笔记(11)——模板匹配
- 蒙面西红柿
- 1,274
单对象匹配
模板匹配和卷积原理很像,模板在原图像上从原点开始滑动,计算模板与图像被模板覆盖区域的差别程度。这个差别程度的计算方法在OpenCV里有6中,然后将每次计算的结果放入一个矩阵中,作为输出结果。假设原图像是A*B大小,模板是a*b大小,则输出结果的矩阵是(A-a+1)*(B-b+1)
这里重点说一下几种匹配方法的区别
- 平方差匹配 CV_TM_SQDIFF:用两者的平方差来匹配,最好的匹配值为0
- 归一化平方差匹配 CV_TM_SQDIFF_NORMED
- 相关匹配 CV_TM_CCORR:用两者的乘积匹配,数值越大表明匹配程度越好
- 归一化相关匹配CV_TM_CCORR_NORMED
- 相关系数匹配 CV_TM_CCOEFF:用两者的相关系数匹配,1表示完美的匹配,-1表示最差的匹配
- 归一化相关系数匹配 CV_TM_CCOEFF_NORMED
一般都使用归一化的匹配方法。
#模板匹配
#第一步,读取灰度图
img = cv2.imread('lena,jpg', 0)
template = cv2.imread('face.jpg', 0)
#第二部,获得模板大小与匹配方法
methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',
'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']
h, w = template.shape[:2]
#第三步,使用每一种方法进行匹配
for meth in methods:
#备份原图
img = img1.copy()
method = eval(meth)
# 应用模板匹配
res = cv2.matchTemplate(img,template,method)
#找到最大值和最小值
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
print(cv2.minMaxLoc(res))
# 如果匹配方法是 TM_SQDIFF or TM_SQDIFF_NORMED, 取最小值
if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
top_left = min_loc
else:
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
#使用左上与右下顶点绘制长方形
cv2.rectangle(img,top_left, bottom_right, 255, 2)
#使用matplotlib绘制原图与添加了长方形的图
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(
多对象匹配
单个匹配是找最大匹配的点,所以只能匹配一次。
对于多对象匹配,我们需要设定一个匹配阈值来匹配多次。
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('mario.jpg')
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
template = cv2.imread('guy.jpg',0)
h, w = template.shape[:2]
res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)
#设定一个阈值。根据算法,有的是越大越好,有的是越小越好
threshold = 0.7
loc = np.where( res >= threshold)
for pt in zip(*loc[::-1]):
bottom_right = (pt[0] + w, pt[1] + h)
cv2.rectangle(img, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)
cv2.imshow('img', img)
cv2.waitKey(0)
#识别图像保存到本地
#cv2.imwrite('res.png',img_rgb)
文章评论