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 相关匹配法:该方法采用乘法操作;数值越大表明匹配程度越好。
  • CV_TM_CCOEFF 相关系数匹配法:1表示完美的匹配;-1表示最差的匹配。
  • CV_TM_SQDIFF_NORMED 计算归一化平方差,计算出来的值越接近0,越相关
  • CV_TM_CCORR_NORMED 计算归一化相关性,计算出来的值越接近1,越相关
  • CV_TM_CCOEFF_NORMED 计算归一化相关系数,计算出来的值越接近1,越相关

待检测的图片如下,需要检测里面金币的位置

需要检测金币的模板如下:

2、基本的多对象模板匹配效果代码如下:

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("001.jpg",img_rgb)
cv2.imshow('img_rgb', img_rgb)
cv2.waitKey(0)

检测效果如下:

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

解决方案:对于使用同一个待检区域使用NMS进行去掉重复的矩形框

3、使用NMS对模板匹配出来的矩形框进行去掉临近重复的,代码如下:

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)

检测效果如下所示:

参考资料:

https://blog.csdn.net/qq_39507748/article/details/104598222
https://docs.opencv.org/3.4/d4/dc6/tutorial_py_template_matching.html
https://blog.csdn.net/mdjxy63/article/details/81037860
https://github.com/rbgirshick/fast-rcnn/blob/master/lib/utils/nms.py
https://www.pyimagesearch.com/2015/02/16/faster-non-maximum-suppression-python/

到此这篇关于opencv模板匹配相同位置去除重复的框的文章就介绍到这了,更多相关opencv模板匹配内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java+opencv3.2.0实现模板匹配

    模板匹配是一项在一幅图像中寻找与另一幅模板图像最匹配(相似)部分的技术. 函数:Imgproc.matchTemplate(Mat image, Mat templ, Mat result, int method) 参数说明: image:源图像 templ:模板图像 result:比较结果 method:匹配算法 匹配算法: TM_SQDIFF 平方差匹配法:该方法采用平方差来进行匹配:最好的匹配值为0:匹配越差,匹配值越大. TM_CCORR 相关匹配法:该方法采用乘法操作:数值越大表明匹配

  • OpenCV 模板匹配

    最近小编实现一个微信小程序「跳一跳」的自动化. 主要涉及到了OpenCV的模板匹配和边缘检测技术,以及Android开发调试工具ADB. 如果放在一起说,感觉内容有些多. 所以,分三期来讲,也能多了解一些东西. 首先介绍模板匹配,然后边缘检测,最后结合ADB实现「跳一跳」自动化. 游戏虽然过时了,但是拿来练练手还是不错的. 编程就该是快乐的,哈哈. / 01 / 模板匹配 模板匹配,就是在整个图像区域里发现与给定子图像相匹配的小块区域. 这里需要一个模板图像(给定的子图像)和一个待检测的图像(原

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

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

  • OpenCV模板匹配matchTemplate的实现

    作用有局限性,必须在指定的环境下,才能匹配成功,是受到很多因素的影响,所以有一定的适应性 模板匹配是一种最原始.最基本的模式识别方法,研究某一特定对象物的图案位于图像的什么地方,进而识别对象物,这就是一个匹配问题. 它是图像处理中最基本.最常用的匹配方法. 模板匹配具有自身的局限性,主要表现在它只能进行平行移动,若原图像中的匹配目标发生旋转或大小变化,该算法无效. 模板匹配就是在整个图像区域发现与给定子图像匹配的小块区域[/code] 工作原理:在待检测图像上,从左到右,从上向下计算模板图像与重

  • 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 相关匹配法:该方法

  • opencv C++模板匹配的简单实现

    目录 一简单实现 二函数及原理讲解 1matchTemplate()参数详解 2minMaxLoc()函数 一 简单实现 #include <opencv2/opencv.hpp> #include<iostream> using namespace cv; using namespace std; int main() { Mat img = imread("52.jpg"); Mat templ = imread("templ.jpg")

  • OpenCV半小时掌握基本操作之模板匹配

    目录 概述 模板匹配 案例一 案例二 [OpenCV]⚠️高手勿入! 半小时学会基本操作 ⚠️ 概述模板 概述 OpenCV 是一个跨平台的计算机视觉库, 支持多语言, 功能强大. 今天小白就带大家一起携手走进 OpenCV 的世界. (第 21 课) 模板匹配 模板匹配 (Template Matching) 和卷积的原理很像. 模板在原图像上从原点开始滑动, 计算模板与图片被模板覆盖的地方的差别程度. 格式: cv2.matchTemplate(image, templ, method, r

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

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

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

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

  • python计算机视觉opencv图像金字塔轮廓及模板匹配

    目录 1.图像金字塔 ①高斯金字塔 ②拉普拉斯金字塔 2.图像轮廓 ①寻找轮廓 ②轮廓特征 ③轮廓绘制 3.模板匹配 ①模板匹配 ②匹配框线绘制 ③多对象匹配 4.直方图统计 ①直方图绘制 ②直方图统计 ③直方图的mask操作 ④直方图均衡化 5.傅里叶变换 1.图像金字塔 ①高斯金字塔 向下采样,数据会越来越少,减少的方式是:将偶数行和列删除 向上采样,数据会越来越多,将图像在每个方向上扩大为原来的两倍,新增的行和列用0来填充.使用先前同样的内核与放大后的图像卷积,获得近似值. 上采样之后,图

  • Python OpenCV实现图像模板匹配详解

    目录 1.什么是模板匹配及模板匹配方法matchTemplate() 介绍 素材准备 2.单模板匹配 2.1 单目标匹配 2.2 多目标匹配 3.多模板匹配 1.什么是模板匹配及模板匹配方法matchTemplate() 介绍 提供一个模板图像,一个目标图像,且满足模板图像是目标图像的一部分,从目标图像中寻找特定的模板图像的过程,即为模板匹配.OpenCV提供了matchTemplate()方法帮助我们实现模板匹配. 该方法语法如下: cv2.matchTemplate(image, templ

随机推荐