机器视觉OpenCV图片模板匹配javascript
养成好习惯:文中文末小广告帮忙点一点java
什么是模板匹配
python
简单来讲模板匹配就是经过现有的模板去与图片进行比较找出图中所匹配的图像。nginx
首先来看一下效果图:
web
左图是模板图片,中图是带测试的图片,右图是匹配的结果
微信
程序将在“中图”中匹配“左图”的模板图片,若是中图中含有模板图片的话,则会在中图画出模板图片的位置(用蓝线圈出来)。app
模板匹配原理:函数
模板匹配是一种用于在较大图像中搜索和查找模板图像位置的方法。为此,OpenCV带有一个函数cv2.matchTemplate()。它只是将模板图像滑动到输入图像上(就像在2D卷积中同样),而后在模板图像下比较模板和输入图像的补丁。OpenCV中实现了几种比较方法。(您能够检查文档以了解更多详细信息)。它返回一个灰度图像,其中每一个像素表示该像素的邻域与模板匹配多少。工具
若是输入图像的大小(WxH)和模板图像的大小(wxh),则输出图像的大小将为(W-w + 1,H-h + 1)。得到结果后,能够使用cv2.minMaxLoc()函数查找最大/最小值在哪里。将其做为矩形的左上角,并以(w,h)做为矩形的宽度和高度。该矩形是您模板的区域。学习
目录:
1.前提
2.两种方法实现
3.后记
1.前提:
程序运行以前先安装一下相关的库
cv2imutils
报错1:
ModuleNotFoundError: No module named 'cv2' (安装cv2)
说明缺乏opencv库
在命令提示符窗口 中,执行下面的命令:
pip install opencv-python
若是以为下载过慢的能够执行下面的命令:(使用了豆瓣源下载,结果和上面是同样的,只不过这个命令安装快一些)
pip install -i https://pypi.doubanio.com/simple/ opencv-python
两种方法实现:
第一次方法:图像模板匹配(最简单)
模板匹配和卷积原理很像,模板在原图像上从原点开始滑动,计算模板与(图像被模板覆盖的地方)的差异程度,这个差异程度的计算方法在OpenCV里有6种,而后将每次的结果放入一个矩阵里,做为结果输出。假如原图形是AXB大小,而模板是axb大小,则输出结果的矩阵是(A-a+1)x(B-b+1)
代码:
"""Created on 2020-11-11
@author: 李运辰"""#模板匹配import numpy as npimport cv2
def cv_show(name,image): cv2.imshow(name,image) cv2.waitKey(0) cv2.destroyAllWindows()
img = cv2.imread("source.jpg")template = cv2.imread("m.jpg")
# 转换为灰度图片gray1 = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)# 读取测试图片并将其转化为灰度图片gray2 = cv2.cvtColor(template,cv2.COLOR_BGR2GRAY)h,w = template.shape[:2]#匹配#TM_SQDIFF 匹配方法,归一化的方法更好用res = cv2.matchTemplate(gray1,gray2,cv2.TM_SQDIFF)#获得极值坐标min_val,max_val,min_loc,max_loc = cv2.minMaxLoc(res)top_left = min_locbottom_right = (top_left[0]+w,top_left[1]+h)#画出标记点cv2.rectangle(img,top_left,bottom_right,255,2)cv_show("img",img)
运行结果:
第二种方法:多尺度模板匹配
多尺度模板匹配实现步骤
步骤1-读取模板图片,并依次执行灰度化和边缘检测处理;
步骤2-读取测试图片,遍历整个尺度空间,进行图片裁剪;
步骤3-依次执行边缘检测和模板匹配,获取到外接矩形;
步骤4-根据结果对测试图片中模板所在的位置进行更新;
步骤5-首先进行位置转换,而后绘制矩形框,最后显示结果。
代码实现:
"""Created on 2020-11-11
@author: 李运辰"""# coding=utf-8# 导入python包import numpy as npimport imutilsimport cv2
# 读取模板图片template = cv2.imread("m.jpg")# 转换为灰度图片template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)# 读取测试图片并将其转化为灰度图片image = cv2.imread('source.jpg')gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 执行边缘检测template = cv2.Canny(template, 50, 200)(tH, tW) = template.shape[:2]# 显示模板#cv2.imshow("Template", template)
found = None
# 循环遍历不一样的尺度for scale in np.linspace(0.2, 1.0, 20)[::-1]: # 根据尺度大小对输入图片进行裁剪 resized = imutils.resize(gray, width = int(gray.shape[1] * scale)) r = gray.shape[1] / float(resized.shape[1])
# 若是裁剪以后的图片小于模板的大小直接退出 if resized.shape[0] < tH or resized.shape[1] < tW: break
# 首先进行边缘检测,而后执行模板检测,接着获取最小外接矩形 edged = cv2.Canny(resized, 50, 200) #匹配 #TM_SQDIFF 匹配方法,归一化的方法更好用 result = cv2.matchTemplate(edged, template, cv2.TM_CCOEFF) (_, maxVal, _, maxLoc) = cv2.minMaxLoc(result)
# 结果可视化 # 绘制矩形框并显示结果 clone = np.dstack([edged, edged, edged]) cv2.rectangle(clone, (maxLoc[0], maxLoc[1]), (maxLoc[0] + tW, maxLoc[1] + tH), (0, 0, 255), 2) #cv2.imshow("Visualize", clone) #cv2.waitKey(0)
# 若是发现一个新的关联值则进行更新 if found is None or maxVal > found[0]: found = (maxVal, maxLoc, r)
# 计算测试图片中模板所在的具体位置,即左上角和右下角的坐标值,并乘上对应的裁剪因子(_, maxLoc, r) = found(startX, startY) = (int(maxLoc[0] * r), int(maxLoc[1] * r))(endX, endY) = (int((maxLoc[0] + tW) * r), int((maxLoc[1] + tH) * r))
# 绘制并显示结果cv2.rectangle(image, (startX, startY), (endX, endY), (0, 0, 255), 2)cv2.imshow("Image", image)cv2.waitKey(0)
运行结果:
3.后记:
若是你们学会这种技术以后,再稍微改进一下,弄错一个小脚本,这样下次玩开心消消乐的那能够直接无敌了,不再用担忧找不到匹配的小方块了,哈哈哈哈。
在集体照的茫茫人海中,你还怕我找不到你???经过模板匹配,直接定位你的位置
最后帮忙点一点文中文末小广告
正文结束!!!!
欢迎关注公众号:Python爬虫数据分析挖掘,方便及时阅读最新文章
记录学习python的点点滴滴;
回复【开源源码】免费获取更多开源项目源码;
公众号每日更新python知识和【免费】工具;
本文已同步到【开源中国】、【腾讯云社区】、【CSDN】;
本文分享自微信公众号 - Python爬虫数据分析挖掘(zyzx3344)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。