zoukankan      html  css  js  c++  java
  • OpenCV--模板匹配

    模板匹配

    模板匹配和卷积原理很像,模板在原图像上从原点开始滑动,计算模板与(图像被模板覆盖的地方)的差别程度,这个差别程度的计算方法在opencv里有6种,然后将每次计算的结果放入一个矩阵里,作为结果输出。假如原图形是AxB大小,而模板是axb大小,则输出结果的矩阵是(A-a+1)x(B-b+1)

    TM_SQDIFF:计算平方不同,计算出来的值越小,越相关 

    TM_CCORR:计算相关性,计算出来的值越大,越相关

    TM_CCOEFF:计算相关系数,计算出来的值越大,越相关

    TM_SQDIFF_NORMED:计算归一化平方不同,计算出来的值越接近0,越相关

    TM_CCORR_NORMED:计算归一化相关性,计算出来的值越接近1,越相关

    TM_CCOEFF_NORMED:计算归一化相关系数,计算出来的值越接近1,越相关

    公式:https://docs.opencv.org/3.3.1/df/dfb/group__imgproc__object.html#ga3a7850640f1fe1f58fe91a2d7583695d

    # 模板匹配
    img = cv2.imread('lena.jpg', 0)
    template = cv2.imread('face.jpg', 0)
    h, w = template.shape[:2] 
    img.shape
    template.shape

    效果:

    (263, 263)
    (110, 85)
    res = cv2.matchTemplate(img, template, cv2.TM_SQDIFF) #也可以写数字
    res.shape

    效果:

    (154, 179)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) #最大值、最小值、最大值坐标、最小值坐标
    min_val
    max_val
    min_loc
    max_loc

    效果:

    39168.0
    74403584.0
    (107, 89)
    (159, 62)
    for meth in methods:
        img2 = img.copy()
    
        # 匹配方法的真值
        method = eval(meth)
        #print (method)
        res = cv2.matchTemplate(img, template, method)
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    
        # 如果是平方差匹配TM_SQDIFF或归一化平方差匹配TM_SQDIFF_NORMED,取最小值
        if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
            top_left = min_loc
        else:
            top_left = max_loc
        bottom_right = (top_left[0] + w, top_left[1] + h)
    
        # 画矩形
        cv2.rectangle(img2, top_left, bottom_right, 255, 2)
    
        plt.subplot(121), plt.imshow(res, cmap='gray')
        plt.xticks([]), plt.yticks([])  # 隐藏坐标轴
        plt.subplot(122), plt.imshow(img2, cmap='gray')
        plt.xticks([]), plt.yticks([])
        plt.suptitle(meth)
        plt.show()

    效果:

     匹配多个对象

    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)
    for pt in zip(*loc[::-1]):  # *号表示可选参数
        bottom_right = (pt[0] + w, pt[1] + h)
        cv2.rectangle(img_rgb, pt, bottom_right, (0, 0, 255), 1)
    
    cv2.imshow('img_rgb', img_rgb)
    cv2.waitKey(0)

    效果:

  • 相关阅读:
    上下伸展的JS菜单
    [ZZ]Debug VBScript with Visual Studio
    面试总结之杂题
    [ZZ]9 Confusing Naming Conventions for Beginners
    Robocopy
    [ZZ]什么是Alpha,Beta,RC,RTM,CTP版
    使用位运算交换两个值,不用临时变量
    学习笔记之编程之美微软技术面试心得(一)
    C#中如何获取系统环境变量
    学习笔记之SQL教程 from W3School
  • 原文地址:https://www.cnblogs.com/SCCQ/p/12293104.html
Copyright © 2011-2022 走看看