原图像:
模板图像:
cv.TM_SQDIFF_NORMED匹配结果:
由于是采用平方差的方式判断相似度,所以值越小越好(越暗越好)
采用cv.TM_CCORR_NORMED结果:
采用相似度进行匹配,因此值越大越好(亮)
采用cv.TM_CCOEFF_NORMED结果:
因为是相似系数,所以值越大越好(亮)
代码部分:
import numpy as np
import cv2 as cv
def template_match_demo(template, target):
# OpenCV提供的模板匹配的方法,依次为“归一化平方差匹配”、“相关性匹配”以及“相关系数匹配”
# 第一种方法越小越好,其余两种越大越好
methods = [cv.TM_SQDIFF_NORMED, cv.TM_CCORR_NORMED, cv.TM_CCOEFF_NORMED]
# 获取模板的尺寸信息
template_h, template_w = template.shape[:2]
# 进行匹配
for method in methods:
"""
image:需要匹配的图像
template:模板
method:匹配方法
result:结果存放(可直接设置变量接收)
mask:遮罩,先定匹配范围
"""
result = cv.matchTemplate(target, template, method)
cv.imshow("result of"+str(method), result)
# 获取结果中最大值或者最小值的位置以及值信息
min_val, max_val, min_loc, max_loc = cv.minMaxLoc(result)
print(min_val, " ", max_val, " ", min_loc, " ", max_loc, "\n")
if method == cv.TM_SQDIFF_NORMED:
# 如果使用平方差作为衡量标准,则需要的是最小值的坐标(该坐标为左上角的坐标)
tl = min_loc
else:
# 否则需要最大值的坐标
tl = max_loc
# 计算得到右下角坐标
br = (tl[0] + template_w, tl[1] + template_h)
# 绘制框图进行标记
"""
image:需要被绘制的图像
p1, p2:左上角以及右下角的坐标
color:颜色
thickness:线的宽度
"""
cv.rectangle(target, tl, br, color=(0, 0, 255), thickness=10)
cv.imshow("match-"+str(method), target)
template = cv.imread("data/butterfly_template.jpg")
target = cv.imread("data/butterfly.jpg")
template_match_demo(template, target)
cv.waitKey(0)
cv.destroyAllWindows()