机器视觉OpenCV图片模板匹配

养成好习惯:文中文末小广告帮忙点一点

什么是模板匹配

简单来说模板匹配就是通过现有的模板去与图片进行比较找出图中所匹配的图像。

首先来看一下效果图:

左图是模板图片,中图是带测试的图片,右图是匹配的结果

程序将在“中图”中匹配“左图”的模板图片,如果中图中含有模板图片的话,则会在中图画出模板图片的位置(用蓝线圈出来)。


模板匹配原理:

模板匹配是一种用于在较大图像中搜索和查找模板图像位置的方法。为此,OpenCV带有一个函数cv2.matchTemplate()。它只是将模板图像滑动到输入图像上(就像在2D卷积中一样),然后在模板图像下比较模板和输入图像的补丁。OpenCV中实现了几种比较方法。(您可以检查文档以了解更多详细信息)。它返回一个灰度图像,其中每个像素表示该像素的邻域与模板匹配多少。

如果输入图像的大小(WxH)和模板图像的大小(wxh),则输出图像的大小将为(W-w + 1,H-h + 1)。获得结果后,可以使用cv2.minMaxLoc()函数查找最大/最小值在哪里。将其作为矩形的左上角,并以(w,h)作为矩形的宽度和高度。该矩形是您模板的区域。


目录:

    1.前提

     2.两种方法实现

     3.后记

1.前提:

程序运行之前先安装一下相关的库

cv2
imutils

报错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 np
import cv2def 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_loc
bottom_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 np
import imutils
import 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】;

「找一找」考你眼力的时候到了!相关推荐

  1. python求完数的因子_「每日一练」巧用python找出1000以内的所有完数

    原标题:「每日一练」巧用python找出1000以内的所有完数 "完数"指的是一个数恰巧等于它的所有因子之和,比如说6,它的因子分别是1,2,3,而6正好等于1+2+3,所以6就是 ...

  2. 复习七天通过软考高级「系统架构师」,我是如何做到的

    前言 软考复习的方式可以分为两种:报班和自学.当然也有加QQ要求共同分摊网课费用的,当然被我义正言辞地无情拒绝.原因很简单:没钱.于是前前后后自学了七天,最终考过了系统架构师.或许我的学习模式不适合你 ...

  3. 「第五篇」全国电子设计竞赛-电源题设计方案总结

    点击上方"大鱼机器人",选择"置顶/星标公众号" 福利干货,第一时间送达! 0  前言 许多朋友给我留言说,有没有电源题目的一些文章可以参考. 为了给大家找更多 ...

  4. 十问旷视印奇、唐文斌:AI企业都在经历「死亡之谷」

    2020-10-16 12:09:19 郭一璞 李根 发自 凹非寺 量子位 报道 | 公众号 QbitAI AI明星公司旷视,刚庆祝了自己的9周岁生日. 以技术和理工天才云集著称的他们,把新的一岁用「 ...

  5. 「田间的精进」的践行者:褚时健——实实在在的人生

    「田间的精进」的践行者.转发一篇去年的文章:向时代的传奇致敬!褚时健--实实在在的人生 导语:51岁,任玉溪卷烟厂厂长:70岁,女儿自杀身亡:71岁,被判无期徒刑:74岁,保外就医:75岁,承包200 ...

  6. 43種能創造「被動收入」的方法,收藏起來吧!

    转载自:https://rich01.com/43-2/ 「我知道現金流很重要,但具體來說,到底該怎麼創造被動收 入呢?」 在一次的讀書會中,一位朋友問到這個問題. 對大多數的人來說, 「被動收入」( ...

  7. 码农们的「血与泪」:新零售「全渠道中台」的前世今身

    作者 | 袁鸣凯,家乐福技术总监, 高知特有限技术公司中国区架构师,HP上海研发技术专家,夸客金融首席架构师,现任家乐福中国区技术总监.多年互联网.企业级SOA.微服务.全渠道中台方面的架构设计实战经 ...

  8. OpenAI当红新星宋飏:最新研究获评「终结扩散模型」,16岁上清华

    一个OpenAI华人大牛,最近引发众人关注. 他刚以一作身份发表的最新生成模型,引爆整个学术圈,让不少人惊呼: 有望「终结扩散模型」,「图像生成领域,要变天了」. 他提出的一致性模型,效果比扩散模型更 ...

  9. 新版「李雷与韩梅梅」深度好文

    阅读文本大概需要 6.3 分钟. 李雷和韩梅梅青梅竹马,一直被邻居们看好,他们俩就读于某镇重点中学,鉴于老师的谆谆教诲: "一定要努力学习,争取考上一所好学校,否则将来找不到好工作" ...

最新文章

  1. 关于Linux服务器配置java环境遇到的问题
  2. rmmod无法卸载驱动_笔记:linux驱动开发(1、了解内核模块)
  3. 内存泄漏的原因及解决办法_编程基础 | C++片段 指针、多态和内存分配
  4. springboot实践1
  5. web服务器 apache_如何配置Apache Web服务器
  6. Java BigDecimal类
  7. IEC61850报告服务(报文解析)
  8. Spring中引用不同xml中的bean
  9. 【PS】黑白照片改为彩色照片
  10. 浅析桌面虚拟化给企业带来的价值
  11. 【LLS-Player】webrtc m94 修改
  12. channel练习题
  13. js定时换图片(图片路径可变)
  14. 网络安全“攻防战”:“魔”“道”大盘点
  15. 不用计算机怎么算根号二,根号怎么打 根号2或3等于多少?
  16. Delphi 多线程编程(1)
  17. 生产者消费者模式解决强耦合问题
  18. Linux下安装和使用杀毒软件AntiVir(ZZ)
  19. Java实现 稀疏矩阵乘积
  20. 数据库:PostgreSQL 和 MySQL对比

热门文章

  1. 天美服务器未响应,王者荣耀服务器上热搜,无数玩家遭遇掉线烦恼,天美该怎么办?...
  2. 纳豆红曲胶囊价格作用怎么样!
  3. ubuntu14.04+cuda7.0+opencv2.4.9
  4. 3G无线上网卡种类介绍
  5. 弱人工智能时代,如何跨越技术与产品的鸿沟?
  6. 如何在集群上运行Shark
  7. 亚洲首台BMD8K切换台开箱
  8. Fighting Girl——那个IT女孩
  9. 云服务器有什么优势和特点?
  10. python加注释_python中加注释