欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

OpenCV 模板匹配去重

程序员文章站 2023-12-25 23:59:51
...

根据不同匹配结果间的距离远近进行去重操作。

检测效果

OpenCV 模板匹配去重

源码

import cv2
import numpy as np
import time

def get_ready():
	#录入模板,主函数仅执行一次,节省资源
    template = cv2.imread('./template.png',0)
    return template

def get_img(cap):
	#从摄像头实时读取一帧图像
    _,img_bgr = cap.read()
    return img_bgr

def match_template(img_bgr,template):
	#调用opencv内部模块进行模板匹配
    img_gray = cv2.cvtColor(img_bgr,cv2.COLOR_BGR2GRAY)
    res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)
    threshold = 0.5		#匹配相似度阈值,越高越精确
    loc = np.where(res>=threshold)		#numpy进行筛选匹配

    loc1 = []		#用于录入目标坐标点
    for i in range(len(list(loc[0]))):
        loc1.append(list(zip(*loc[::-1]))[i])
    return loc1,res

def elim_same(loc1):
	#根据匹配结果的坐标间距进行去重
    count = len(loc1)
    threshold1 = 10		#10个像素点以内则视为同一目标
    i = 0

    while(i<count):
        for j in range(count):
            if j != i:
                if np.abs(loc1[j][0]-loc1[i][0]) <= threshold1:		#x坐标
                    if np.abs(loc1[j][1]-loc1[i][1]) <= threshold1:	#y坐标
                        loc1[j] = loc1[i]		#近似坐标归一处理
        i += 1

    resl = set(loc1)		#去除归一后的多余结果,完成去重
    return resl

def draw_write(img_bgr,resl,res):
	#绘制图框与相似度数字
    for pt in resl:
        cv2.rectangle(img_bgr,pt,(pt[0]+w,pt[1]+h),(0,255,0),2)
        template_num = round(res[pt[1]][pt[0]],2)	#四舍五入取两位小数
        font = cv2.FONT_HERSHEY_SIMPLEX
        cv2.putText(img_bgr,'%s'%template_num,(pt[0],pt[1]-5),font,0.5,(0,255,0),1,cv2.LINE_AA)

def off(cap):
	#键盘检测与摄像头释放
    k = cv2.waitKey(5) & 0xFF
    if k == 27:
        cv2.destroyAllWindows()
        cap.release()
    return k

def main():
    k = 0
    template = get_ready()
    global w,h
    w,h = template.shape[::-1]
    
    cap = cv2.VideoCapture(0)

    while True:
        img_bgr = get_img(cap)
        loc1,res = match_template(img_bgr,template)
        resl = elim_same(loc1)
        draw_write(img_bgr,resl,res)
        cv2.imshow('detected',img_bgr)
        time.sleep(0.1)
        k = off(cap)
        if k == 27:
            break


if __name__ == '__main__':
    main()

代码难点

矩阵处理,较为抽象。

上一篇:

下一篇: