opencv学习笔记(九)
模板匹配:
在模板匹配中,我们引入函数cv2.matchTemplate()函数来执行模板匹配的操作
res = cv2.matchTemplate(image, template, method, result=None, mask=None)
image
: 输入的源图像,可以是灰度图像或彩色图像。template
: 要匹配的模板图像,必须与源图像具有相同的数据类型和通道数。method
: 模板匹配方法,用于指定匹配的算法。常见的方法有:
cv2.TM_SQDIFF
: 平方差匹配法,计算平方不同,计算出来的值越小就越相关;cv2.TM_SQDIFF_NORMED
: 归一化平方差匹配法,计算归一化平方不同,计算出来的值越靠近0,越相关;cv2.TM_CCORR
: 相关性匹配法,计算相关性,计算出来的值越大,越相关;cv2.TM_CCORR_NORMED
: 归一化相关性匹配法,计算归一化相关性,计算出来的值越接近1,越相关;cv2.TM_CCOEFF
: 相关系数匹配法,计算出来的值越大,越相关;cv2.TM_CCOEFF_NORMED
: 归一化相关系数匹配法,计算归一化相关系数,计算出来的值越接近1,越相关。
result
(可选): 输出的匹配结果图像,与源图像大小相同,数据类型为浮点型。mask
(可选): 掩码图像,指定要匹配的图像区域。
函数返回一个包含匹配结果的浮点型数组(或图像)。可以通过 cv2
.minMaxLoc()
函数找到结果数组中的最大值和最小值,以及对应的位置。
#模板匹配 #假设原图的大小是A*B,而模板大小是a*b,那么输出结果的矩阵是(A-a+1)*(B-b+1) import cv2 import numpy as np from matplotlib import pyplot as plt img = cv2.imread('C:/Users/hellou/Desktop/self-image.jpg', 0) template = cv2.imread('C:/Users/hellou/Desktop/face-imge.jpg', 0) h, w = template.shape[:2]#取图片的长和宽 print(img.shape) print(template.shape) """TM_SQDIFF:计算平方不同,计算出来的值越小,越相关 TM_CCORR:计算相关性,计算出来的值越大,越相关 TM_CCOEFF:计算相关系数,计算出来的值越大,越相关 TM_SQDIFF_NORMED:计算归一化平方不同,计算出来的值越接近0,越相关 TM_CCORR_NORMED:计算归一化相关性,计算出来的值越接近1,越相关 TM_CCOEFF_NORMED:计算归一化相关系数,计算出来的值越接近1,越相关 建议使用带有归一化的方法""" methods = ['cv2.TM_SQDIFF','cv2.TM_CCORR','cv2.TM_CCOEFF','cv2.TM_SQDIFF_NORMED','cv2.TM_CCORR_NORMED','cv2.TM_CCOEFF_NORMED'] res = cv2.matchTemplate(img, template, 1) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) for meth in methods: img2 = img.copy() #匹配方法的真值 method = eval(meth)#将字符串转变为符号的赋值 print(method) res = cv2.matchTemplate(img, template, method) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) #如果是平方差匹配TM_SQDIFF或归一化平方差匹配TM_SQIDFF_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(img2, top_left, bottom_right, 255, 2) #OpenCV 中的 rectangle 函数可以在一幅图像上绘制矩形。该函数的格式如下: #cv2.rectangle(image, start_point, end_point, color, thickness) #参数解释: #image:要在其上绘制矩形的图像 #start_point:矩形的左上角坐标 #end_point:矩形的右下角坐标 #color:矩形的颜色,可以是 BGR 或者 RGB 的三通道元组 #thickness:线条的粗细,如果设置为 -1,表示矩形是填充的""" plt.subplot(121), plt.imshow(res, cmap='gray') plt.xticks([]),plt.yticks([]) #隐藏坐标轴 plt.subplot(122), plt.imshow(img2, cmap='gray') plt.xticks([]),plt.yticks([]) plt.suptitle(meth) plt.show()
匹配多个对象:
import cv2 # 读取源图像和模板图像 image = cv2.imread('image.png') template1 = cv2.imread('template1.png') template2 = cv2.imread('template2.png') # 定义匹配方法 method = cv2.TM_CCOEFF_NORMED # 执行模板匹配 result1 = cv2.matchTemplate(image, template1, method) result2 = cv2.matchTemplate(image, template2, method) # 设置阈值 threshold = 0.8 # 寻找满足阈值条件的匹配结果 locations1 = np.where(result1 >= threshold) locations2 = np.where(result2 >= threshold) # 绘制矩形框标记匹配位置 w1, h1 = template1.shape[::-1] w2, h2 = template2.shape[::-1] for pt in zip(*locations1[::-1]): cv2.rectangle(image, pt, (pt[0] + w1, pt[1] + h1), (0, 255, 0), 2) for pt in zip(*locations2[::-1]): cv2.rectangle(image, pt, (pt[0] + w2, pt[1] + h2), (0, 0, 255), 2) # 显示匹配结果 cv2.imshow('Matched Image', image) cv2.waitKey(0) cv2.destroyAllWindows()