先来玩一个小游戏:
给你一张图片,
让你在里面找到下面这个图片形状的位置。
多久能找到?
通过左上角的黄色五边形定位来找,应该可以快速找到。
不过今天我们不用眼睛找,靠程序来找。
在opencv 中,有一个模板匹配的方法,详细原理可以看这篇文章:https://docs.opencv.org/4.5.4/de/da9/tutorial_template_matching.html。
模板匹配是一项在一幅图像中寻找与另一幅模板图像最匹配(相似)部分的技术.
我们的目标是检测最匹配的区域:
为了确定匹配区域, 需要滑动模板图像和原图像进行比较 :
通过 滑动, 图像块一次移动一个像素 (从左往右,从上往下). 在每一个位置, 都进行一次度量计算来表明它是 “好” 或 “坏” 地与那个位置匹配 (或者说块图像和原图像的特定区域有多么相似).
对于 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 做一个消息轰炸机。http://mpvideo.qpic.cn/0bf2xmagcaaawqagsoa53nqvbo6dmg5qayia.f10002.mp4?dis_k=1b2694564e55f75bb9c669e42525039f&dis_t=1637201303&vid=wxv_2008237594303578113&format_id=10002&support_redirect=0&mmversion=false
也可以做一个鼠标连点器,解决那些无聊重复的操作,还可以做一些伪AI游戏。自动找到目标物,跳过,或者点击。http://mpvideo.qpic.cn/0bf2nmaf4aaapaafrzq54rqva26dlzvqaxqa.f10003.mp4?dis_k=75ac0852101e15317ea36d95047b1015&dis_t=1637201303&vid=wxv_2008229079094706177&format_id=10003&support_redirect=0&mmversion=false
http://mpvideo.qpic.cn/0bf2v4aesaaa3eam6oiw6bqvbl6djgxqasia.f10002.mp4?dis_k=b6de17cd6b90ef40d55e0a87aaf1ede6&dis_t=1637201303&vid=wxv_2001083915179966464&format_id=10002&support_redirect=0&mmversion=false
你还能想到用这个做什么有意思或者实用的作品,欢迎留言分享~
python知识库
(全文完)