1. 程式人生 > >opencv學習(十五):模板匹配

opencv學習(十五):模板匹配

引言

        模板匹配是在一幅影象中尋找一個特定目標的方法之一。這種方法的原理非常簡單,遍歷影象中的每一個可能的位置,比較各處與模板是否“相似”,當相似度足夠高時,就認為找到了我們的目標。

匹配方法

         在 OpenCV 中,提供了相應的匹配函式完成這個操作:matchTemplate、 minMaxLoc

         matchTemplate 函式:在模板和輸入影象之間尋找匹配,獲得匹配結果影象 
         minMaxLoc 函式:在給定的矩陣中尋找最大和最小值,並給出它們的位置

         在具體介紹這兩個函式之前呢,我們還要介紹一個概念,就是如何來評價兩幅影象是否“相似”。 
OpenCV 提供了 6 種計算兩幅影象相似度的方法:

  • 差值平方和匹配 CV_TM_SQDIFF
  • 標準化差值平方和匹配 CV_TM_SQDIFF_NORMED
  • 相關匹配 CV_TM_CCORR
  • 標準相關匹配 CV_TM_CCORR_NORMED
  • 相關匹配 CV_TM_CCOEFF
  • 標準相關匹配 CV_TM_CCOEFF_NORMED

 方法介紹

         下面就分別來介紹。首先,先給出幾個符號: 
T(x,y)  用來表示我們的模板。I(x,y) 是我們的目標影象。 R(x,y) 是用來描述相似度的函式。

差值平方和匹配 CV_TM_SQDIFF

這類方法利用影象與模板各個畫素差值的平方和來進行匹配,最好匹配為 0。 匹配越差,匹配值越大。

                                       
標準化差值平方和匹配 CV_TM_SQDIFF_NORMED

這個方法其實和差值平方和演算法是類似的。只不過對影象和模板進行了標準化操作。

                                 


這種標準化操作可以保證當模板和影象各個畫素的亮度都乘上了同一個係數時,相關度不發生變化。

也就是說當 I(x,y)和T(x,y) 變為k×I(x,y)和k×T(x,y) 時,R(x,y)不發生變化。

相關匹配 CV_TM_CCORR

這類方法採用模板和影象的互相關計算作為相似度的度量方法,所以較大的數表示匹配程度較高,0標識最壞的匹配效果。

                                           
標準化相關匹配 CV_TM_CCORR_NORMED

這個方法和 標準化差值平方和匹配 類似,都是去除了亮度線性變化對相似度計算的影響。可以保證影象和模板同時變亮或變暗k倍時結果不變。

                                           
相關匹配 CV_TM_CCOEFF

這種方法也叫做相關匹配,但是和上面的 CV_TM_CCORR 匹配方法還是有不通過的。簡單的說,這裡是把影象和模板都減去了各自的平均值,使得這兩幅影象都沒有直流分量。

                                                  
標準相關匹配 CV_TM_CCOEFF_NORMED

這是 OpenCV 支援的最複雜的一種相似度演算法。這裡的相關運算就是數理統計學科的相關係數計算方法。具體的說,就是在減去了各自的平均值之外,還要各自除以各自的方差。經過減去平均值和除以方差這麼兩步操作之後,無論是我們的待檢影象還是模板都被標準化了,這樣可以保證影象和模板分別改變光照亮不影響計算結果。計算出的相關係數被限制在了 -1 到 1 之間,1 表示完全相同,-1 表示兩幅影象的亮度正好相反,0 表示兩幅影象之間沒有線性關係。

                                                 

例項演示:

程式碼如下

#匯入cv模組
import cv2 as cv
import numpy as np
'''
    匹配方法:
    差值平方和匹配 CV_TM_SQDIFF
    標準化差值平方和匹配 CV_TM_SQDIFF_NORMED
    相關匹配 CV_TM_CCORR
    標準相關匹配 CV_TM_CCORR_NORMED
    相關匹配 CV_TM_CCOEFF
    標準相關匹配 CV_TM_CCOEFF_NORMED
'''
def template_demo():
    tpl=cv.imread("F:/Projects/images/tpl.png")
    target=cv.imread("F:/Projects/images/target1.png")
    cv.imshow("template image",tpl)
    cv.imshow("target image",target)
    methods=[cv.TM_SQDIFF_NORMED,cv.TM_CCORR_NORMED,cv.TM_CCOEFF_NORMED]
    th,tw=tpl.shape[:2]
    for md in methods:
        print(md)
        result=cv.matchTemplate(target,tpl,md)
        min_val,max_val,min_loc,max_loc=cv.minMaxLoc(result)
        if md==cv.TM_SQDIFF_NORMED:
            tl=min_loc
        else:
            tl=max_loc
        br=(tl[0]+tw,tl[1]+th)
        cv.rectangle(target,tl,br,(0,0,255),2)
        cv.imshow("match-"+np.str(md),target)

print("------------Hi,Python!-------------")
# 讀取影象,支援 bmp、jpg、png、tiff 等常用格式
src = cv.imread("F:/Projects/images/1.jpg")
#建立視窗並顯示影象
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
cv.imshow("input image",src)   #顯示原圖
template_demo()
cv.waitKey(0)
#釋放視窗
cv.destroyAllWindows()

執行效果: