22.OpenCV的模板匹配
模板匹配是让模板图像在输入图像中滑动,逐像素遍历整个图像进行比较,查找出与模板图像最匹配的部分。
单目标匹配是指输入图像中只存在一个可能的匹配结果。
OpenCV中使用cv2.matchTemplate()函数用于执行匹配操作,其基本格式如下:
result = cv2.matchTemplate(image, templ, method)
image为输入图像, 必须是8位或32位浮点类型
templ为模板图像, 不能大于image, 且数据类型要和image相同
method为匹配方法, 匹配方法不同, 返回的结果会有所不同, 可用的匹配方法:
cv2.TM_SQDIFF:以方差结果为依据进行匹配, 完全匹配时结果为0, 否则为一个很大的值
cv2.TM_SQDIFF_NORMED:标准(归一化)方差匹配
cv2.TM_CCORR:相关匹配, 将输入图像与模板图像相乘, 乘积越大匹配度越高, 乘积为0时匹配度最低
cv2.TM_CCORR_NORMED:标准(归一化)相关匹配
cv2.TM_CCOEFF:相关系数匹配, 将输入图像与其均值的相关值和模板图像与其均值的相关值进行匹配, 结果为1表示完美匹配, -1表示糟糕匹配, 0表示没有任何相关性
cv2.TM_CCOEFF_NORMED:标准(归一化)相关系数匹配
result为返回的结果, 它是一个numpy.ndarray对象。若输入图像大小为W * H, 模板图像大小为w * h, 则result的大小为(W-w+1)*(H-h+1), 其中的每个值都表示对应位置的匹配结果。
OpenCV中使用cv2.minMaxLoc()函数处理匹配结果,其基本格式如下:
minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(src)
src为cv2.matchTemplate()函数返回的结果
minVal为src中的最小值, 不存在时可以为NULL(空值)
maxVal为src中的最大值, 不存在时可以为NULL(空值)
minLoc为src中的最小值的位置, 不存在时可以为NULL(空值)
maxLoc为src中的最大值的位置, 不存在时可以为NULL(空值)
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('bee.jpg') # 打开输入图像,默认为BGR格式
cv2.imshow('original', img)
temp = cv2.imread('template.jpg') # 打开模板图像
cv2.namedWindow('template', cv2.WINDOW_NORMAL)
cv2.imshow('template', temp)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY, dstCn=1) # 转换为单通道灰度图像
temp_gray = cv2.cvtColor(temp, cv2.COLOR_BGR2GRAY, dstCn=1) # 转换为单通道灰度图像
res = cv2.matchTemplate(img_gray, temp_gray, cv2.TM_SQDIFF) # 执行匹配
cv2.imshow('Matching Result', res)
plt.imshow(res, cmap = 'gray') # 以灰度图像格式显示匹配结果
plt.title('Matching Result')
plt.axis('off')
plt.show()
h, w = temp_gray.shape # 获取模板图像的高度和宽度
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) # 返回最值和位置
top_left = min_loc # 最小值为最佳匹配,获得其位置
bottom_right = (top_left[0] + w, top_left[1] + h) # 获得匹配范围的右下角位置
cv2.rectangle(img, top_left, bottom_right, (255, 0, 0), 2) # 绘制匹配范围,蓝色边框
cv2.imshow('Detected Result', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
多目标匹配是指输入图像中存在多个可能的匹配结果。在使用cv2.matchTemplate()函数执行了匹配操作后,根据匹配方法设置阈值,匹配结果中低于或高于阈值的就是符合条件的匹配目标。
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('bee2.jpg')
temp = cv2.imread('template.jpg')
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY, dstCn=1)
temp_gray = cv2.cvtColor(temp, cv2.COLOR_BGR2GRAY, dstCn=1)
th, tw= temp_gray.shape
img1h, img1w=img_gray.shape
res = cv2.matchTemplate(img_gray,temp_gray,cv2.TM_CCOEFF_NORMED) # 执行匹配操作
mloc=[] # 用于保存符合条件的匹配位置
threshold = 0.68 # 设置匹配度阈值
for i in range(img1h - th):
for j in range(img1w - tw):
if res[i][j] >= threshold: # 保存小于阈值的匹配位置
mloc.append((j, i))
for pt in mloc:
cv2.rectangle(img, pt, (pt[0] + tw, pt[1] + th), (255, 0, 0), 2) # 标准匹配位置,蓝色矩形
cv2.imshow('result', img) # 显示结果
cv2.waitKey(0)
cv2.destroyAllWindows()
OpenCV-Python测试用图片、中文官方文档、opencv-4.5.4源码
以上内容介绍了OpenCV-Python的模板匹配的基础操作,有关Python、数据科学、人工智能等文章后续会不定期发布,请大家多多关注,一键三连哟(●’◡’●)。