OpenCV(11):模板匹配实例讲解

这篇具有很好参考价值的文章主要介绍了OpenCV(11):模板匹配实例讲解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

引言:

在OpenCV中,模板匹配是一种图像处理技术,用于在一个大的图像中查找和定位一个小的目标图像(也称为模板)。

通俗而言,就是通过一张图片找到和另一张图片相似的部分。

从此章开始,opencv系列所有的之后更新的博客都会更注重实际应用,而不是仅仅简单讲解一个小方法是怎么应用的,会涉及到一些其他的方法,对于有些可能出现的代码看不懂的问题,我会放在文章的最后一节。

代码实战:

在模板匹配中,我们首先选定一个小的图像作为目标图像,然后在一个大的输入图像中滑动这个小的目标图像,从而寻找与其最相似的部分。具体实现时,可以使用多种算法来计算相似度,例如平方差和、相关系数、均方误差等等。

核心方法cv2.matchTemplate()是OpenCV中用于实现模板匹配的API函数。该函数可以在一张大图中查找一个小图像,并输出目标区域的位置。以下是cv2.matchTemplate()函数的详细讲解:

函数原型:

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

参数说明:

  • image: 大图像,类型为ndarray。
  • templ: 小图像(模板),类型为ndarray。
  • method: 匹配算法,可选值包括
    • cv2.TM_CCOEFF、
    • cv2.TM_CCOEFF_NORMED、
    • cv2.TM_CCORR、
    • cv2.TM_CCORR_NORMED、
    • cv2.TM_SQDIFF、
    • cv2.TM_SQDIFF_NORMED。

其中,cv2.TM_CCOEFF和cv2.TM_CCOEFF_NORMED表示相关系数匹配;cv2.TM_CCORR和cv2.TM_CCORR_NORMED表示相关性匹配;cv2.TM_SQDIFF和cv2.TM_SQDIFF_NORMED表示平方差匹配。有兴趣可以了解一下原理。

返回值说明:

retval是一个矩阵,大小为(N-M+1, M-N+1),其中N和M分别为大图像和小图像的高和宽。矩阵中的每个元素表示原始图像中与模板匹配度的一个指标,匹配越好,则值越大。

代码示例:

此次图像匹配我们用的素材如下:

大图:

cv2.matchtemplate,opencv,计算机视觉,图像处理

小图:

cv2.matchtemplate,opencv,计算机视觉,图像处理

 图像模板匹配就是在大图上找出小图的内容来。

完整代码:

import cv2

def cv_show(title,img):
    cv2.imshow(title,img)
    cv2.waitKey(0) 
    cv2.destroyAllWindows()
    return

#读取两个图像
template = cv2.imread('the_bird.png',0)#读取灰度图
cv_show('img',template)#展示图象
img = cv2.imread('bird.jpg',0)
cv_show('img',img)


# 获取小图像的高和宽
h, w = template.shape[:2]

#不同的方法模板匹配的方式不同
methodology =[cv2.TM_CCOEFF,cv2.TM_CCOEFF_NORMED,cv2.TM_CCORR,cv2.TM_CCORR_NORMED,cv2.TM_SQDIFF,cv2.TM_SQDIFF_NORMED]
# cv2.TM_CCOEFF:相关系数匹配。该方法计算输入图像和模板图像之间的相关系数,值越大表示匹配程度越好。
# cv2.TM_CCOEFF_NORMED:标准归一化相关系数匹配。该方法计算输入图像和模板图像之间的标准归一化相关系数,也就是相关系数除以两个图像各自的标准差的乘积。值越大表示匹配程度越好。
# cv2.TM_CCORR:相关性匹配。该方法计算输入图像和模板图像之间的相关性,值越大表示匹配程度越好。
# cv2.TM_CCORR_NORMED:标准归一化相关性匹配。该方法计算输入图像和模板图像之间的标准归一化相关性,也就是相关性除以两个图像各自的标准差的乘积。值越大表示匹配程度越好。
# cv2.TM_SQDIFF:平方差匹配。该方法计算输入图像和模板图像之间的平方差,值越小表示匹配程度越好。
# cv2.TM_SQDIFF_NORMED:标准归一化平方差匹配。该方法计算输入图像和模板图像之间的标准归一化平方差,也就是平方差除以两个图像各自的标准差的乘积。值越小表示匹配程度越好。

method = methodology[1]#选了一个cv2.TM_CCOEFF_NORMED方法进行图像匹配,匹配方式为比较模板和图像中各个区域的标准归一化相关系数
res = cv2.matchTemplate(img, template, method)#比较完成的结果存储在res中,是一个ndarray类型的

# 获取匹配结果中的最大值和最小值
#通过左上角点的位置,加上之前获取的小图像的宽和高h,w,就可以把图像在原图中的那个位置框出来了
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)#最主要的是知道图像位置_loc


#不同的匹配算法,计算匹配到的位置的方式不同
if method in [cv2.TM_SQDIFF,cv2.TM_SQDIFF_NORMED]:
    top_left = min_loc
else:
    top_left = max_loc

#通过左上角点的坐标和h,w计算右下角点的坐标
bottom_right = (top_left[0]+w, top_left[1]+h)#[0]为横坐标,[1]为纵坐标,横加宽纵加高就是右下角的点坐标

#绘制矩形
resoult_img = cv2.rectangle(img.copy(),top_left,bottom_right,255,1)

cv_show('img',resoult_img)

代码讲解:

  1. 读取两个图像:template表示要匹配的小图片,img表示需要在其中寻找小图片的大图片。

  2. 通过shape属性获取小图像的高h和宽w是几个像素点。

  3. 选择不同的方法模板匹配的方式,包括cv2.TM_CCOEFF、 cv2.TM_CCOEFF_NORMED、cv2.TM_CCORR、cv2.TM_CCORR_NORMED、cv2.TM_SQDIFF、cv2.TM_SQDIFF_NORMED。不同的方法模板匹配比较的东西也不同。概述我在代码标注中写了。此次实验中,我们选取cv2.TM_CCOEFF_NORMED方法进行图像匹配。

  4. 调用cv2.matchTemplate()函数进行图像匹配,比较完成的结果存储在res中,是一个ndarray类型的。具体来说就是原图中每一块区域所有像素点的比较结果,都存储在这个矩阵里。

  5. 获取匹配结果中的最大值和最小值以及对应的位置信息。最大值就代表最优匹配

  6. 不同的匹配算法,计算匹配到的位置的方式不同。如果是平方差匹配,则选取最小值点作为匹配结果;否则选取最大值点。匹配结果的坐标就是最优匹配的左上角的坐标。通过左上角点的位置,加上之前获取的小图像的宽和高h,w,就可以把图像在原图中的那个位置框出来了。

  7. 通过左上角点的坐标和h,w计算右下角点的坐标。

  8. 计算完右下角的点坐标之后,我们就有了左上角和右下角点的坐标。通过cv2.rectangle()方法再原图中将匹配的区域画出来。

返回结果:

先用cv_show方法展示了模板图像,此时咱们读取的是灰度图所以是灰色的。

 cv2.matchtemplate,opencv,计算机视觉,图像处理

按任意键继续,展示了需要进行样板匹配的图像:

cv2.matchtemplate,opencv,计算机视觉,图像处理

 按任意键继续后,展示的图像是用矩形框将匹配的区域框选出来的图像

cv2.matchtemplate,opencv,计算机视觉,图像处理

匹配多个对象:

上面的代码就是一个简单的图像匹配的具体流程。而再实际应用中,我们可能会面临一个情况就是我的图像中有多个区域(或者说对象)和模板匹配。那么此时我们就不是用

min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

这行代码去进行找res对象中最佳的匹配了,而是设置一个阈值,找出相似程度超过阈值的区域。

此次我们示例图像如下:我用画图软件画的

cv2.matchtemplate,opencv,计算机视觉,图像处理

 样板如下:

cv2.matchtemplate,opencv,计算机视觉,图像处理

完整代码:

import cv2
import numpy as np

def cv_show(title,img):
    cv2.imshow(title,img)
    cv2.waitKey(0) 
    cv2.destroyAllWindows()
    return

#读取两个图像
template = cv2.imread('target.png',0)#读取灰度图目标
img = cv2.imread('targets.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)


# 获取小图像的高和宽
h, w = template.shape[:2]
method = cv2.TM_CCOEFF_NORMED

#进行匹配,匹配结果存放在res中
res = cv2.matchTemplate(gray, template, method)

#与之前直接读取最大最小值不同,此次我们需要的是res中多个目标的结果,所以在此设置一个阈值
threshold = 0.8 
loc = np.where(res >= threshold)#阈值为0.8,即取百分之80匹配的
for loc in zip(*loc[::-1]):
    bottom_right = (loc[0]+w, loc[1]+h)
    cv2.rectangle(img,loc, bottom_right, 255, 2 )

cv_show('resoult',img)

代码讲解:

  1. 此次我读取图像的方式有些不同,之前我是直接读取灰度图,但是这次我读取了BGR图像然后将转化成了灰度图。因为我注意到上一个项目示例中最终展示的结果不是彩色的
  2. 中间一段的代码和上文相同。h,w获取样板的宽和高的像素点,匹配方式和之前一样。大家也可以试试其他的method,通常情况下,归一化对比方法(后缀带_NORMED的方法)要比原方法效果好些,通过归一化可以消除图像亮度、对比度等因素的影响,使得匹配结果更加准确。但是,由于归一化处理可能会使得图像失去一些细节信息。
  3. 设置了一个阈值0.8,用np.where()方法找出res中超过阈值的区域坐标,遍历所有的坐标,将其绘制再原图上。需要注意的是,由于where方法返回的坐标是先纵坐标再横坐标,所以需要将其反转。
  4. 展示图片。

cv2.matchtemplate,opencv,计算机视觉,图像处理

 

在本章节中可能遇到的问题的一些提示:

  1. cv_show()方法是我自己定义的一个方法,主要功能就是调用了一下opencv自带的图像展示函数cv2.imshow(),和一个按任意键继续的功能cv2.waitKey(0) ,以及关闭窗口cv2.destroyAllWindows(),对于没看过我前几篇文章的人可能会有些疑惑,在此讲一下。
  2. cv2.imread()中如果输入参数0,就会直接读取图像的灰度图,如果不传这个参数就是读取彩色图像BGR格式的。
  3. 对于cv2.rectangle()方法,这个方法会改变传入对象,就是他会在传入的img上画矩形,而不是返回一个新的img,所以一般情况下传入的图像是img.copy()。那在多对象匹配中,我利用for循环进行矩形框的绘制,此时就不能传入copy的图像了,如果用copy图像进行绘制,那么每次都只画一个框,最后结果也是只有最后遍历的那一个框。
  4. 对于zip(*loc[::-1]),其中loc[::-1]是对原坐标转置的一个操作,原因是因为where方法返回的是纵横坐标而不是横纵坐标。不转置其实也可以,但是跟咱代码习惯有些不同,后面的右下角坐标计算方式也有些不同,所以这边还是转置一下。而*是一个捷报操作,就是将矩阵拆成单独的一个个元素。而对于zip()方法就是将解包解出来的单个元素又拼在一块变成一个元组,以便for循环遍历。总之这一个代码其实就是对坐标进行一个转置的操作。
  5. opencv中,图像格式默认是BGR而不是RGB
  6. 关于坐标。在计算机图形学中,图像实际上是一个像素矩阵,而文章中说的坐标实际上就是矩阵中各个元素的索引。由于矩阵的索引是按行列从左到右,从上到下的形式进行的。所以计算机图形学中的坐标系和平时的平面直角坐标系不同,他的y轴是反的。

有什么问题可以在评论区讨论哈哈哈文章来源地址https://www.toymoban.com/news/detail-758740.html

到了这里,关于OpenCV(11):模板匹配实例讲解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 008 OpenCV matchTemplate 模板匹配

    目录 一、环境 二、模板匹配算法原理 三、代码演示 本文使用环境为: Windows10 Python 3.9.17 opencv-python 4.8.0.74 cv.matchTemplate 是OpenCV库中的一个函数,用于在图像中查找与模板匹配的特征。它的主要应用场景是在图像处理、计算机视觉和模式识别等领域。 算法原理: cv.matchTempl

    2024年02月05日
    浏览(39)
  • opencv形状匹配(cv2.matchShape)

       

    2024年02月14日
    浏览(43)
  • opencv基础49-图像轮廓02-矩特征cv2.moments()->(形状分析、物体检测、图像识别、匹配)

    矩特征(Moments Features)是用于图像分析和模式识别的一种特征表示方法,用来描述图像的形状、几何特征和统计信息。矩特征可以用于识别图像中的对象、检测形状以及进行图像分类等任务。 矩特征通过计算图像像素的高阶矩来提取特征。这些矩可以表示图像的中心、尺度

    2024年02月13日
    浏览(40)
  • python使用cv2获取截图中的匹配项目的中心位置

    在OpenCV中,cv2.matchTemplate()函数用于在大图中查找与小图(模板)匹配的区域,但并不会直接返回一个区域的box。 想要获取匹配区域的边界框(box),以及中心的位置,这样后续好进行自动化操作,。以下是一种方法: 首先,使用cv2.matchTemplate()函数找到匹配的区域。 然后,

    2024年02月09日
    浏览(33)
  • 【OpenCV】透视变换——cv2.getPerspectiveTransform()与cv2.warpPerspective()详解

    目录 什么是透视变换? 函数解析 cv2.getPerspectiveTransform() dst = warpPerspective() 代码实现 透视变换(Perspective Transformation)是指利用透视中心、像点、目标点三点共线的条件,按透视旋转定律使承影面(透视面)绕迹线(透视轴)旋转某一角度,破坏原有的投影光线束,仍能保持

    2024年02月05日
    浏览(56)
  • opencv图像旋转和翻转,cv2.flip,cv2.rotate

    目录 翻转图像 图像旋转         opencv中使用cv2.filp可以实现图像翻转 src:输入图像 flipCode:flipCode 一个标志来指定如何翻转数组;0表示上下翻转,正数表示左右翻转,负数表示上下左右都翻转。 dst:输出图像         下面代码对图像进行不同旋转。         opencv中使

    2024年02月15日
    浏览(70)
  • opencv-python库 cv2 图形绘制 cv2.line()cv2.rectangle()cv2.circle()cv2.ellipse()cv2.polylines()cv2.putText

    cv2.line() 是 OpenCV 中的一个函数,用于在图像上绘制直线。这个函数需要指定图像、线的起点和终点坐标、线的颜色、线的宽度以及线的类型。 下面是 cv2.line() 函数的详细参数说明: 参数解释: 下面是一个使用 cv2.line() 绘制直线的简单示例: 在这个例子中,我们创建了一个

    2024年04月23日
    浏览(46)
  • 【OpenCV常用函数:颜色空间转换、阈值化】cv2.cvtColor()+cv2.threshold()

    对图像进行颜色空间的转换 对图像进行阈值化/二值化

    2024年02月13日
    浏览(61)
  • cv2(OpenCV)下载安装

     cv2对应库是OpenCV,官网下载链接:https://www.lfd.uci.edu/~gohlke/pythonlibs/#opencv 最好下载对应python版本的,通过pip命令安装可能会出现版本过高或者过低的问题,导致import cv2没问题,但是内部函数无法调用。 如果不想下载到本地,也可以通过命令安装: pip install opencv-python==4.5.

    2024年02月08日
    浏览(37)
  • 【OpenCV常用函数:轮廓检测+外接矩形检测】cv2.findContours()+cv2.boundingRect()

    对具有黑色背景的二值图像寻找白色区域的轮廓,因此一般都会先经过cvtColor()灰度化和threshold()二值化后的图像作为输入。 例如,如下的轮廓检测出的结果contours和hierarchy。 根据轮廓点检测对应轮廓的外接矩形

    2024年02月13日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包