【模板匹配】——图像预处理(OpenCV)

目录

19 模板匹配

19.1 模板匹配

19.2 匹配方法

19.2.1 平方差匹配

19.2.2 归一化平方差匹配

19.2.3 相关匹配

19.2.4 归一化相关匹配

19.2 5 相关系数匹配

19.2.6 归一化相关系数匹配

19.3 绘制轮廓


19 模板匹配

19.1 模板匹配

定义:用模板图在目标图中不断滑动,通过某种方法来判断是否匹配成功,找到模板图所在位置。

特点:

  • 不会有边缘填充。
  • 类似于卷积,滑动比较,挨个比较像素。
  • 返回结果大小是:目标图大小-模板图大小+1

19.2 匹配方法

语法:

res = cv2.matchTemplate(image,templ,method)

参数说明:

  • image:原图像,灰度图像或彩色图像(匹配将在每个通道上独立进行)。

  • templ:模板图像,也是灰度图像或与原图像相同通道数的彩色图像。

  • method:匹配方法,可以是以下之一:

    • cv2.TM_CCOEFF

    • cv2.TM_CCOEFF_NORMED

    • cv2.TM_CCORR

    • cv2.TM_CCORR_NORMED

    • cv2.TM_SQDIFF

    • cv2.TM_SQDIFF_NORMED

返回值:

一个结果矩阵,这个矩阵的大小与原图像相同。矩阵的每个元素表示原图像中相应位置与模板图像匹配的相似度。

匹配方法不同,返回矩阵的值的含义也会有所区别。:

  1. cv2.TM_SQDIFFcv2.TM_SQDIFF_NORMED

    返回值越接近0,表示匹配程度越好。最小值对应的最佳匹配位置。

  2. cv2.TM_CCORRcv2.TM_CCORR_NORMED

    返回值越大,表示匹配程度越好。最大值对应的最佳匹配位置。

  3. cv2.TM_CCOEFFcv2.TM_CCOEFF_NORMED

    返回值越大,表示匹配程度越好。最大值对应的最佳匹配位置。

19.2.1 平方差匹配

cv2.TM_SQDIFF

19.2.2 归一化平方差匹配

cv2.TM_SQDIFF_NORMED

与平方差匹配类似,只不过需要将值统一到0到1

19.2.3 相关匹配

cv2.TM_CCORR

19.2.4 归一化相关匹配

cv2.TM_CCORR_NORMED

19.2 5 相关系数匹配

cv2.TM_CCOEFF

19.2.6 归一化相关系数匹配

cv2.TM_CCOEFF_NORMED

19.3 绘制轮廓

找的目标图像中匹配程度最高的点,我们可以设定一个匹配阈值来筛选出多个匹配程度高的区域。

语法1:

loc = np.where(array>0.8) # loc包含array中所有大于0.8的**元素索引**的数组

np.where(condition) 是 NumPy 的一个函数,当条件为真时,返回满足条件的元素的索引。

语法2:

zip(*loc)
  • *loc 是解包操作,将 loc 中的多个数组拆开,作为单独的参数传递给 zip
  • zip 将这些数组按元素一一配对,生成一个迭代器,每个元素是一个元组,表示一个坐标点。

案例:

x=list([[1,2,3,4,3],[23,4,2,4,2]])
print(list(zip(*x)))#[(1, 23), (2, 4), (3, 2), (4, 4), (3, 2)]

案例:

import numpy as np
import cv2 as cv

# 读图
img = cv.imread("./images/game.png")# 目标图
# print(img.shape)
temp = cv.imread("./images/temp.png")# 模板图
# print(temp.shape)
# 转灰度
img_gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)# 目标图转灰度
temp_gray = cv.cvtColor(temp,cv.COLOR_BGR2GRAY)# 模板图转灰度
# 模板匹配
# cv2.matchTemplate(目标图,模板图,匹配方式)
res = cv.matchTemplate(img_gray,temp_gray,cv.TM_CCOEFF_NORMED)
print(res.shape)
# print(res)
# 设置阈值,使用np.where获取条件的坐标
threshold = 0.8
loc = np.where(res>=threshold)# loc ==> (y,x) 因为先行后列(会获取匹配程度大于等于阈值的结果的索引位置,[[y1,y2,...yn],[x1,x2,...xn]])
# print(loc,type(loc),res[loc[0][0],loc[1][0]])
# 获取模板宽高
h,w = temp.shape[:2]
# 解包,拿坐标
for pt in zip(*loc):# pt==>(y,x)
    leftupper = pt[::-1] # (x,y)
    rightbottom = (pt[1]+w,pt[0]+h) # (x+w,y+h)
    # 绘制出匹配的部分,框出来
    cv.rectangle(img,leftupper,rightbottom,(0,255,0),2,cv.LINE_AA)
cv.imshow("img",img)
cv.waitKey(0)
cv.destroyAllWindows()

输出:

练习:

import cv2 as cv
import numpy as np

# 读取图像
img = cv.imread("./my_image/image.jpg")
temp = cv.imread("./my_image/templ.jpg")
# 获取模板宽高
h,w = temp.shape[:2]
# 转灰度
img_gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)# 目标图转灰度
temp_gray = cv.cvtColor(temp,cv.COLOR_BGR2GRAY)# 模板图转灰度
# 模板匹配
res = cv.matchTemplate(img,temp,cv.TM_CCOEFF_NORMED)
print(res)
# 设置阈值
threshold = 0.9
# 使用np.where获取条件的坐标
loc = np.where(res >= threshold)
print(loc)
# 解包,拿坐标
for pt in zip(*loc):
    left_upper = pt[::-1]
    right_bottom = (pt[1] + w , pt[0] + h)
    # 绘制出匹配的部分,框出来
    cv.rectangle(img,left_upper,right_bottom,(0,0,255),1)
# 显示图像
cv.imshow("img",img)
cv.waitKey()
cv.destroyAllWindows()

输出:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值