先来玩一个小游戏:
给你一张图片,
让你在里面找到下面这个图片形状的位置。
多久能找到?
通过左上角的黄色五边形定位来找,应该可以快速找到。
不过今天我们不用眼睛找,靠程序来找。
在opencv 中,有一个模板匹配的方法,详细原理可以看这篇文章:https://docs.opencv.org/4.5.4/de/da9/tutorial_template_matching.html。
模板匹配是一项在一幅图像中寻找与另一幅模板图像最匹配(相似)部分的技术.
它是怎么实现的?
我们需要2幅图像:
原图像 (I): 在这幅图像里,我们希望找到一块和模板匹配的区域
模板 (T): 将和原图像比照的图像块
我们的目标是检测最匹配的区域:
为了确定匹配区域, 需要滑动模板图像和原图像进行比较 :
通过 滑动, 图像块一次移动一个像素 (从左往右,从上往下). 在每一个位置, 都进行一次度量计算来表明它是 “好” 或 “坏” 地与那个位置匹配 (或者说块图像和原图像的特定区域有多么相似).
对于 T 覆盖在 I 上的每个位置,你把度量值 保存 到 结果图像矩阵 (R) 中. 在 R 中的每个位置(x,y) 都包含匹配度量值:
上图就是 TM_CCORR_NORMED 匹配方法处理后的结果图像 R . 最白的位置代表最高的匹配. 正如您所见, 红色椭圆框住的位置很可能是结果图像矩阵中的最大数值, 所以这个区域 (以这个点为顶点,长宽和模板图像一样大小的矩阵) 被认为是匹配的.
按照这个原理,通过下面的代码,快速就可以识别到目标物。
import cv2
# 加载图片
tpl = cv2.imread("1.png")
target = cv2.imread("2.png")
th,tw = tpl.shape[:2] #获取模板图像的高宽
method = cv2.TM_CCOEFF_NORMED # 标准相关匹配算法
# 开始匹配
result = cv2.matchTemplate(target, tpl, method)
# 在给定的矩阵中寻找最大和最小值
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
# 如果最大值超过0.7(自己定义的),表示匹配,完全一样基本上就接近1了
if max_val > 0.7:
print(1)
tl = max_loc #tl是左上角点
br = (tl[0]+tw,tl[1]+th) #br右下点
cv2.rectangle(target,tl,br,(0,0,255),5)#画矩形
cv2.imshow('result',target)
cv2.waitKey(0)
这个模板匹配方法,可以在很多地方用到,同样也可以做出很多有意思的东西。
比如在QQ聊天界面中找到按钮位置。
配合按键鼠标自动操作,可以做一个恶搞的消息轰炸机,具体可以看用 python 做一个消息轰炸机。
也可以做一个鼠标连点器,解决那些无聊重复的操作,还可以做一些伪AI游戏。自动找到目标物,跳过,或者点击。
你还能想到用这个做什么有意思或者实用的作品,欢迎留言分享~
(全文完)
长按二维码,加关注!叶子陪你玩