OpenCV-模板匹配 单个对象匹配、多个对象匹配

概念

模板匹配与剪辑原理很像,模板在原图像上从原点开始浮动,计算模板(图像被模板覆盖的地方)的差别程度,这个差别程度的计算方法在opencv里有六中,人后将每次计算的结果放入一个矩阵里面,作为输出结果。加入原图形是A*B大小,则输出结果的矩阵是(A-a+1)(B-b+1)
在这里插入图片描述
匹配完之后,告诉你每一个位置的结果,(结果会因为匹配算法不同而不同)
官网
在这里插入图片描述
在这里插入图片描述
建议用带归一化的,更可靠

步骤

单个目标的模板匹配

代码:

第一步:读入目标图片,读入模板图片,对目标图片和模板图片进行灰度化操作

第二步:使用cv2.matchtemplate(img, template, cv2.TM_CCOEFF_NORMED) 进行模板匹配,获得大量的ret结果
第三步:使用min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(ret) # 找出最大值数所在的位置

第四步:使用cv2.rectangle(original, max_loc, (max_loc[0] + w, max_loc[1] + h), (0, 0, 255), 2) 进行画图操作

第五步:我们对上述的方法进行循环,尝试各种方法所得到的结果

单个对象匹配

代码实现一

import cv2
import numpy as np
import matplotlib.pyplot as plt

#读入图片,模板个原图
original = cv2.imread('girl.png')
img = cv2.imread('girl.png', 0)
template = cv2.imread('girlFace.png', 0)
template.shape
img.shape
methods = ['cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCOEFF', 'cv2.TM_SQDIFF_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_CCORR', 'cv2.TM_CCORR_NORMED']
ret = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED)
ret.shape

在这里插入图片描述
在这里插入图片描述
用max_loc = cv2.minMaxLoc(ret) 定位

在这里插入图片描述
在这里插入图片描述

for method in methods:
    draw_img = img.copy()
    
    #匹配方法的真值
    op = eval(method)
    ret = cv2.matchTemplate(img, template, op)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(ret)
    
    #如果是平方差匹配cv2.TM_SQDIFF或归一化平方差匹配'cv2.TM_SQDIFF_NORMED,取最小值
    if method in ['cv2.TM_SQDIFF_NORMED', 'cv2.TM_SQDIFF']: #指定为实际的方法,不能是字符串
        loc = min_loc
    else:
        loc = max_loc
    rect = cv2.rectangle(draw_img, loc, (loc[0] + w, loc[1] + h), (0, 0, 255), 2)#左上角这个点,弄出这个框框
    
    plt.subplot(121)
    plt.imshow(ret, cmap='gray')
    plt.title(method)
    plt.subplot(122)
    plt.imshow(rect, cmap='gray')
    plt.title(method)
    plt.show()

在这里插入图片描述
在这里插入图片描述

代码实现二

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

多个对象匹配

多目标匹配, 多目标匹配使用的是一个阈值,当大于这个阈值时,我们认为已经获得一个目标的匹配值

而使用cv2.matchTemplate匹配出的ret实际是一些上述指标的数值

代码实现

第一步:读入图片,对目标图片和模板进行灰度化
第二步:匹配模板,获得ret
第三步:使用np.where(ret>0.8) 删选合适的位置,这个位置是(0, 2)即0表示竖的,2表示横着的
第四步:使用index[::-1]将位置进行调换,使用*index[::-1]使得矩阵发生拆分,使用zip进行两两组合
第五步:使用cv2.rectangle进行画多个矩阵
第六步:使用cv2.imshow展示图片

original = cv2.imread('maliao.png')
img = cv2.imread('maliao.png', 0)
template = cv2.imread('maliaojinbi.png', 0)
h, w = template.shape[:2]
ret = cv2.matchTemplate(img, template, cv2.TM_CCORR_NORMED)

#取匹配程度大于80%的坐标
index = np.where(ret > 0.8)

draw_img = original.copy()
for i in zip(*index[::-1]):	#*代表可选参数
    rect = cv2.rectangle(draw_img, i, (i[0]+w, i[1]+h), (0, 0, 255), 1)

cv2.imshow('rect', np.hstack((original, rect)))
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值