我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Python+Opencv实现图像匹配功能(模板匹配)

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Python+Opencv实现图像匹配功能(模板匹配)

本文实例为大家分享了Python+Opencv实现图像匹配功能的具体代码,供大家参考,具体内容如下

1、原理

简单来说,模板匹配就是拿一个模板(图片)在目标图片上依次滑动,每次计算模板与模板下方的子图的相似度,最后就计算出了非常多的相似度;
如果只是单个目标的匹配,那只需要取相似度最大值所在的位置就可以得出匹配位置;
如果要匹配多个目标,那就设定一个阈值,就是说,只要相似度大于比如0.8,就认为是要匹配的目标。

1.1 相似度度量指标

  • 差值平方和匹配 CV_TM_SQDIFF
  • 标准化差值平方和匹配 CV_TM_SQDIFF_NORMED
  • 相关匹配 CV_TM_CCORR
  • 标准相关匹配 CV_TM_CCORR_NORMED
  • 相关匹配 CV_TM_CCOEFF
  • 标准相关匹配 CV_TM_CCOEFF_NORMED

1.2 计算步骤

有一张模板图像Templa和一张较大的待搜索图像Image,模板匹配是一种用于在较大图像中搜索和查找模板图像位置的方法。
具体就是将模板图​​像滑动到输入图像上(就像在卷积操作一样),然后在模板图像下比较模板和输入图像的子图的相似度。
它返回一个灰度图像,其中每个像素表示该像素的邻域与模板匹配的相似度。如果输入图像的大小(WxH)和模板图像的大小(wxh),则输出图像的大小将为(W-w+ 1,H-h + 1)。 获得相似度图像之后,在其上查找最大相似度所在的像素。将其作为匹配区域矩形的左上角,并以(w,h)作为矩形的宽度和高度。该矩形是与模板匹配的区域。

2、代码实现

2.1 单模板匹配单个目标

代码如下:


# 相关系数匹配方法: cv2.TM_CCOEFF
res = cv2.matchTemplate(img, template, cv2.TM_CCOEFF)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

left_top = max_loc   # 左上角
right_bottom = (left_top[0] + w, left_top[1] + h)   # 右下角
cv2.rectangle(img, left_top, right_bottom, 255, 2)  # 画出矩形位置

plt.subplot(121), plt.imshow(res, cmap='gray')
plt.title('Matching Result'), plt.xticks([]), plt.yticks([])

plt.subplot(122), plt.imshow(img, cmap='gray')
plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
plt.show()

2.2 单模板匹配多个目标

目标照片:mario.jpg

模板照片:mario_coin.jpg

代码如下:


import cv2
import numpy as np
img_rgb = cv2.imread('mario.jpg')
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
template = cv2.imread('mario_coin.jpg', 0)
h, w = template.shape[:2]
 
res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
threshold = 0.8
# 取匹配程度大于%80的坐标
loc = np.where(res >= threshold)
#np.where返回的坐标值(x,y)是(h,w),注意h,w的顺序
for pt in zip(*loc[::-1]):  
    bottom_right = (pt[0] + w, pt[1] + h)
    cv2.rectangle(img_rgb, pt, bottom_right, (0, 0, 255), 2)
cv2.imwrite("img.jpg",img_rgb)
cv2.imshow('img', img_rgb)
cv2.waitKey(0)

检测结果如下:

3、算法精度优化

  • 多尺度模板匹配
  • 旋转目标模板匹配
  • 非极大值抑制

通过上图可以看到对同一个图有多个框标定,需要去重,只需要保留一个

解决方案:对于使用同一个待检区域使用NMS(非极大值抑制)进行去掉重复的矩形框

NMS 原理

对于Bounding Box的列表B及其对应的置信度S,采用下面的计算方式。选择具有最大score的检测框M,将其从B集合中移除并加入到最终的检测结果D中。通常将B中剩余检测框中与M的IoU大于阈值Nt的框从B中移除,重复这个过程,直到B为空。

ps. 重叠率(重叠区域面积比例IOU)常用的阈值是 0.3 ~ 0.5.

代码如下:


import cv2
import time
import numpy as np
 
def py_nms(dets, thresh):
    """Pure Python NMS baseline."""
    #x1、y1、x2、y2、以及score赋值
    # (x1、y1)(x2、y2)为box的左上和右下角标
    x1 = dets[:, 0]
    y1 = dets[:, 1]
    x2 = dets[:, 2]
    y2 = dets[:, 3]
    scores = dets[:, 4]
    #每一个候选框的面积
    areas = (x2 - x1 + 1) * (y2 - y1 + 1)
    #order是按照score降序排序的
    order = scores.argsort()[::-1]
    # print("order:",order)
 
    keep = []
    while order.size > 0:
        i = order[0]
        keep.append(i)
        #计算当前概率最大矩形框与其他矩形框的相交框的坐标,会用到numpy的broadcast机制,得到的是向量
        xx1 = np.maximum(x1[i], x1[order[1:]])
        yy1 = np.maximum(y1[i], y1[order[1:]])
        xx2 = np.minimum(x2[i], x2[order[1:]])
        yy2 = np.minimum(y2[i], y2[order[1:]])
        #计算相交框的面积,注意矩形框不相交时w或h算出来会是负数,用0代替
        w = np.maximum(0.0, xx2 - xx1 + 1)
        h = np.maximum(0.0, yy2 - yy1 + 1)
        inter = w * h
        #计算重叠度IOU:重叠面积/(面积1+面积2-重叠面积)
        ovr = inter / (areas[i] + areas[order[1:]] - inter)
        #找到重叠度不高于阈值的矩形框索引
        inds = np.where(ovr <= thresh)[0]
        # print("inds:",inds)
        #将order序列更新,由于前面得到的矩形框索引要比矩形框在原order序列中的索引小1,所以要把这个1加回来
        order = order[inds + 1]
    return keep
 
def template(img_gray,template_img,template_threshold):
    '''
    img_gray:待检测的灰度图片格式
    template_img:模板小图,也是灰度化了
    template_threshold:模板匹配的置信度
    '''
 
    h, w = template_img.shape[:2]
    res = cv2.matchTemplate(img_gray, template_img, cv2.TM_CCOEFF_NORMED)
    start_time = time.time()
    loc = np.where(res >= template_threshold)#大于模板阈值的目标坐标
    score = res[res >= template_threshold]#大于模板阈值的目标置信度
    #将模板数据坐标进行处理成左上角、右下角的格式
    xmin = np.array(loc[1])
    ymin = np.array(loc[0])
    xmax = xmin+w
    ymax = ymin+h
    xmin = xmin.reshape(-1,1)#变成n行1列维度
    xmax = xmax.reshape(-1,1)#变成n行1列维度
    ymax = ymax.reshape(-1,1)#变成n行1列维度
    ymin = ymin.reshape(-1,1)#变成n行1列维度
    score = score.reshape(-1,1)#变成n行1列维度
    data_hlist = []
    data_hlist.append(xmin)
    data_hlist.append(ymin)
    data_hlist.append(xmax)
    data_hlist.append(ymax)
    data_hlist.append(score)
    data_hstack = np.hstack(data_hlist)#将xmin、ymin、xmax、yamx、scores按照列进行拼接
    thresh = 0.3#NMS里面的IOU交互比阈值
 
    keep_dets = py_nms(data_hstack, thresh)
    print("nms time:",time.time() - start_time)#打印数据处理到nms运行时间
    dets = data_hstack[keep_dets]#最终的nms获得的矩形框
    return dets
if __name__ == "__main__":
    img_rgb = cv2.imread('mario.jpg')#需要检测的图片
    img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)#转化成灰色
    template_img = cv2.imread('mario_coin.jpg', 0)#模板小图
    template_threshold = 0.8#模板置信度
    dets = template(img_gray,template_img,template_threshold)
    count = 0
    for coord in dets:
        cv2.rectangle(img_rgb, (int(coord[0]),int(coord[1])), (int(coord[2]),int(coord[3])), (0, 0, 255), 2)
    cv2.imwrite("result.jpg",img_rgb)

检测结果如下:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Python+Opencv实现图像匹配功能(模板匹配)

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Python OpenCV怎么实现图像模板匹配

今天小编给大家分享一下Python OpenCV怎么实现图像模板匹配的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1.什么是
2023-06-29

Opencv Python实现两幅图像匹配

本文实例为大家分享了Opencv Python实现两幅图像匹配的具体代码,供大家参考,具体内容如下 原图import cv2img1 = cv2.imread('SURF_2.jpg', cv2.IMREAD_GRAYSCALE) img1
2022-06-02

OpenCV-Python如何实现多模板匹配

小编给大家分享一下OpenCV-Python如何实现多模板匹配,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!多模板匹配在上一篇的实战中,我们通过人物眼睛的子图,找
2023-06-15

opencv C++模板匹配的实现方法

这篇文章主要介绍“opencv C++模板匹配的实现方法”,在日常操作中,相信很多人在opencv C++模板匹配的实现方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”opencv C++模板匹配的实现方法
2023-06-29

python OpenCV实现图像特征匹配示例详解

这篇文章主要为大家介绍了python OpenCV实现图像特征匹配示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-05-17

python中opencv图像金字塔轮廓及模板匹配是怎样的

这篇文章给大家介绍python中opencv图像金字塔轮廓及模板匹配是怎样的,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1.图像金字塔①高斯金字塔向下采样,数据会越来越少,减少的方式是:将偶数行和列删除向上采样,数据
2023-06-25

python实现模糊匹配

题目:模糊匹配, ‘?’代表一个字符, *代表任意多个字符。给一段明确字符比如avdjnd 以及模糊字符比如*dj?dji?ejj,判断二者是否匹配。若能匹配输出”Yes”, 否则输出“No”(为了方便阅读,代码里面输出Ture or Fa
2023-01-31

python如何基于OpenCV模板匹配识别图片中的数字

小编给大家分享一下python如何基于OpenCV模板匹配识别图片中的数字,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!程序目标单个数字模板:(这些单个模板是我自
2023-06-14

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录