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)

检测结果如下:

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

(0)

相关推荐

  • Python使用Opencv实现图像特征检测与匹配的方法

    特征检测是计算机对一张图像中最为明显的特征进行识别检测并将其勾画出来.大多数特征检测都会涉及图像的角点.边和斑点的识别.或者是物体的对称轴. 角点检测 是由Opencv的cornerHarris函数实现,其他函数参数说明如下: cv2.cornerHarris(src=gray, blockSize=9, ksize=23, k=0.04) # cornerHarris参数: # src - 数据类型为 float32 的输入图像. # blockSize - 角点检测中要考虑的领域大小. #

  • Opencv Python实现两幅图像匹配

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

  • OpenCV-Python实现多模板匹配

    模板匹配的作用在图像识别领域作用可大了.那什么是模板匹配? 模板匹配,就是在一幅图像中寻找另一幅模板图像最匹配(也就是最相似)的部分的技术. 多模板匹配 在上一篇的实战中,我们通过人物眼睛的子图,找出了其在图像中出现位置.但是,有些情况下,并不仅仅只有一次,比如我们讲解傅里叶变换时,曾介绍一张草原的狮子图.如果匹配某个草,可能单个图像内会有很多,这个时候就要找出多个匹配结果. 而函数cv2.minMaxLoc()仅仅能找出最值,无法给出所有匹配区域的位置信息.所以,要想匹配多个结果,就需要进行如

  • OpenCV-Python模板匹配人眼的实例

    什么是模板匹配 模板匹配是指在当前图像A内寻找与图像B最相似的部分,可以理解找茬,但是这里是找出一样的信息. 一般我们将图像A称为输入图像,将图像B称为模板图像.模板匹配的原理就是将模板B图像在图像A上滑动遍历,找出与其匹配的部分. 模板匹配函数 在OpenCV中,它给我们提供了cv2.matchTemplate()函数来完成模板匹配.其函数的完整定义如下: def matchTemplate(image, templ, method, result=None, mask=None): imag

  • Python和OpenCV进行多尺度模板匹配实现

    目录 1. 效果图 2. 原理 3. 步骤 4. 源码 5. 参考 这篇博文将实现如何将标准模板匹配扩展到多尺度,从而使其更加健壮.使其可以处理模板和输入图像大小不同的匹配. 1. 效果图 模板匹配问题:对于模板和图像中不一致的情况,会发生错误检测. 如下图左侧模板小,右侧图像中大,虽然完全一致,只是大小不一样,却未被检测到. 优化:多尺度模板匹配,对于模板和图像中有平移和缩放的情况可以完美工作. 如下图: 多尺度模板匹配,gif 详细效果图: 2. 原理 使用cv2.matchTemplate

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

    前言 本博客主要实现利用OpenCV的模板匹配识别图像中的数字,然后把识别出来的数字输出到txt文件中,如果识别失败则输出"读取失败". 操作环境: OpenCV - 4.1.0 Python 3.8.1 程序目标 单个数字模板:(这些单个模板是我自己直接从图片上截取下来的) 要处理的图片: 终端输出: 文本输出: 思路讲解 代码讲解 首先定义两个会用到的函数 第一个是显示图片的函数,这样的话在显示图片的时候就比较方便了 def cv_show(name, img): cv2.imsh

  • Python开发之基于模板匹配的信用卡数字识别功能

    环境介绍 Python 3.6 + OpenCV 3.4.1.15 原理介绍 首先,提取出模板中每一个数字的轮廓,再对信用卡图像进行处理,提取其中的数字部分,将该部分数字与模板进行匹配,即可得到结果. 模板展示 完整代码 # !/usr/bin/env python # -*- coding: utf-8 -*- # @Time: 2020/1/11 14:57 # @Author: Martin # @File: utils.py # @Software:PyCharm import cv2

  • opencv-python图像配准(匹配和叠加)的实现

    图像配准需是指对不同条件下得到的两幅或多幅图像进行匹配.叠加的过程.最简单的做法就是求得原图像到目标图像之间的透视变换矩阵,将原图像按照矩阵进行变换,就可以得到和目标图像相似的效果.透视变换是将成像投影到一个新的视平面,也称作投影映射. 透视变换实质上是将二维的图片变换到三维的坐标系中之后再变换到另一个二维坐标系,与仿射变换相比透视变换实现的效果要多一些.求解精确矩阵和透视变换可以很容易地在opencv-python中实现. import cv2 as cv import numpy as np

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

    本文实例为大家分享了Python+Opencv实现图像匹配功能的具体代码,供大家参考,具体内容如下 1.原理 简单来说,模板匹配就是拿一个模板(图片)在目标图片上依次滑动,每次计算模板与模板下方的子图的相似度,最后就计算出了非常多的相似度: 如果只是单个目标的匹配,那只需要取相似度最大值所在的位置就可以得出匹配位置: 如果要匹配多个目标,那就设定一个阈值,就是说,只要相似度大于比如0.8,就认为是要匹配的目标. 1.1 相似度度量指标 差值平方和匹配 CV_TM_SQDIFF 标准化差值平方和匹

  • Python OpenCV中的drawMatches()关键匹配绘制方法

    目录 作用说明 函数原型 参数详解 结果 作用说明 该方法被用于绘制关键点的匹配情况.我们看到的许多匹配结果都是使用这一方法绘制的——一左一右两张图像,匹配的关键点之间用线条链接. 函数原型 cv.drawMatches( img1, keypoints1, img2, keypoints2, matches1to2, outImg[, matchColor[, singlePointColor[, matchesMask[, flags]]]]) -> outImg cv.drawMatche

  • python opencv实现图像矫正功能

    本文实例为大家分享了python opencv实现图像矫正的具体代码,供大家参考,具体内容如下 问题简介 一般的我们对图像中的目标进行分析和检测时,往往目标具有一定的倾斜角度,自然环境中正面向我们的目标实际是很少的,那将这些倾斜的目标“扶正”的过程就就叫做图像矫正. 透视变换demo 图像矫正使用的主要技术是透视变换.python-opencv 透视变换demo如下: import cv2 import numpy as np img = cv2.imread('/home/pzs/图片/1.j

  • opencv模板匹配相同位置去除重复的框

    使用opencv自带的模板匹配 1.目标匹配函数:cv2.matchTemplate() res=cv2.matchTemplate(image, templ, method, result=None, mask=None) image:待搜索图像 templ:模板图像 result:匹配结果 method:计算匹配程度的方法,主要有以下几种: CV_TM_SQDIFF 平方差匹配法:该方法采用平方差来进行匹配:最好的匹配值为0:匹配越差,匹配值越大. CV_TM_CCORR 相关匹配法:该方法

  • Python OpenCV学习之特征点检测与匹配详解

    目录 背景 一.Harris角点 二.Shi-Tomasi角点检测 三.SIFT关键点 四.SIFT描述子 五.SURF 六.ORB 七.暴力特征匹配(BF) 八.FLANN特征匹配 九.图像查找 总结 背景 提取图像的特征点是图像领域中的关键任务,不管在传统还是在深度学习的领域中,特征代表着图像的信息,对于分类.检测任务都是至关重要的: 特征点应用的一些场景: 图像搜索:以图搜图(电商.教育领域) 图像拼接:全景拍摄(关联图像拼接) 拼图游戏:游戏领域 一.Harris角点 哈里斯角点检测主要

  • Python OpenCV实现识别信用卡号教程详解

    目录 通过与 OpenCV 模板匹配的 OCR 信用卡 OCR 结果 总结 今天的博文分为三个部分. 在第一部分中,我们将讨论 OCR-A 字体,这是一种专为辅助光学字符识别算法而创建的字体. 然后我们将设计一种计算机视觉和图像处理算法,它可以: 本地化信用卡上的四组四位数字. 提取这四个分组中的每一个,然后单独分割 16 个数字中的每一个. 使用模板匹配和 OCR-A 字体识别 16 个信用卡数字中的每一个. 最后,我们将看一些将信用卡 OCR 算法应用于实际图像的示例. 通过与 OpenCV

随机推荐