模板匹配

模板匹配

模板匹配原理

定義:模板匹配就是在整個圖像區域發現與給定字圖像匹配的最小區域

條件:需要有一個模板圖像T,一個待檢測的圖像——源圖像 I

工作方法:在待檢測圖像I上,從左到右,從上向下計算模板圖像與重疊字圖像的匹配度,匹配程度越大,兩者相同的可能性越大。

函數介紹:
cv2.matchTemplate(image, templ, method, result=None, mask=None)

  • 用模板圖像在輸入圖像(大圖)上滑動,並在每一個位置對模板圖像和與其對應的輸入圖像的子區域進行比較。
  • OpenCV提供了6種不同的比較方法。
  • 返回的結果是一個灰度圖像,每一個像素值表示了此區域與模板的匹配程度。

cv2.minMaxLoc(src, mask=None)

  • 來找到其中的最小值和最大值的位置了。
  • 第一個值爲矩形左上角的點(位置),(w,h)爲moban模板矩形的寬和高。
  • 這個矩形就是找到的模板區域了。

匹配方法介紹

  • TM_SQDIFF(方差匹配法)
    在這裏插入圖片描述
  • TM_SQDIFF_NORMED(歸一化方差匹配法)
    在這裏插入圖片描述
  • TM_CCORR(相關性匹配法)
    在這裏插入圖片描述
  • TM_CCORR_NORMED(歸一化的相關性匹配法)
    在這裏插入圖片描述
  • TM_CCOEFF(相關係數匹配法)
    在這裏插入圖片描述
    • 約束
      在這裏插入圖片描述
      在這裏插入圖片描述
  • TM_CCOEFF_NORMED(歸一化相關係數匹配法)
    在這裏插入圖片描述
單對象模板匹配
import cv2
import numpy as np
from matplotlib import pyplot as plt

plt.close('all')

src = cv2.imread('messi5_s.png', 1)
if src is None:
    print('Could not open or find the image')
    exit(0)
print(src.shape)
img2 = src.copy()
template = cv2.imread('messi5_temp.png', 1)
if template is None:
    print('Could not open or find the template')
    exit(0)
print(template.shape)

h, w = template.shape[:2]
print("w = %d, h = %d" % (w, h))

methods = ['cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED', 'cv2.TM_CCORR', 'cv2.TM_CCORR_NORMED',
           'cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED']

for meth in methods:
    img = img2.copy()
    # eval語句用來計算存儲在字符串中的有效python表達式
    method = eval(meth)
    # 使用模板匹配
    res = cv2.matchTemplate(img, template, method)
    minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(res)
    # 使用不同方法的比較,對結果的解釋不同
    if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
        topLeft = minLoc
    else:
        topLeft = maxLoc
    bottomRight = (topLeft[0] + w, topLeft[1] + h)

    cv2.rectangle(img, topLeft, bottomRight, (0, 0, 255), 5)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    plt.subplot(121), plt.imshow(res, cmap='gray')
    plt.title('Matching res'), plt.xticks([]), plt.yticks([])
    plt.subplot(122), plt.imshow(img, cmap='gray')
    plt.title('Deteced point'), plt.xticks([]), plt.yticks([])
    plt.suptitle(meth)

    plt.show()

效果

  • 方差匹配法,歸一化方差匹配法
    在這裏插入圖片描述
  • 相關性匹配法,歸一化的相關性匹配法
    在這裏插入圖片描述
  • 相關係數匹配法,歸一化相關係數匹配法
    在這裏插入圖片描述
多對象模板匹配

使用閾值找出匹配完成的對象所在的位置
np.where():獲取對象的具體位置

import cv2
import numpy as np
from matplotlib import pyplot as plt

plt.close('all')

src = cv2.imread('Match_T_1.png', 1)
if src is None:
    print('Could not open or find the image')
    exit(0)
print(src.shape)
cv2.imshow("ori", src)
imgGray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
template = cv2.imread('Match_T_2.png', 0)
if template is None:
    print('Could not open or find the template')
    exit(0)
print(template.shape)

h, w = template.shape[:2]
print("w = %d, h = %d" % (w, h))

res = cv2.matchTemplate(imgGray, template, cv2.TM_CCOEFF_NORMED)
threshold = 0.8

loc = np.where(res >= threshold)
for pt in zip(*loc[::-1]):
    cv2.rectangle(src, pt, (pt[0] + w, pt[1] + h), (255, 0, 0), 2)
cv2.imshow('deteced points', src)
cv2.waitKey(0)
cv2.destroyAllWindows()

效果
在這裏插入圖片描述

附錄
cv2.matchTemplate()函數說明
def matchTemplate(image, templ, method, result=None, mask=None): # real signature unknown; restored from __doc__
    """
    matchTemplate(image, templ, method[, result[, mask]]) -> result
    .   @brief Compares a template against overlapped image regions.
    .   
    .   The function slides through image , compares the overlapped patches of size \f$w \times h\f$ against
    .   templ using the specified method and stores the comparison results in result . Here are the formulae
    .   for the available comparison methods ( \f$I\f$ denotes image, \f$T\f$ template, \f$R\f$ result ). The summation
    .   is done over template and/or the image patch: \f$x' = 0...w-1, y' = 0...h-1\f$
    .   
    .   After the function finishes the comparison, the best matches can be found as global minimums (when
    .   #TM_SQDIFF was used) or maximums (when #TM_CCORR or #TM_CCOEFF was used) using the
    .   #minMaxLoc function. In case of a color image, template summation in the numerator and each sum in
    .   the denominator is done over all of the channels and separate mean values are used for each channel.
    .   That is, the function can take a color template and a color image. The result will still be a
    .   single-channel image, which is easier to analyze.
    .   
    .   @param image Image where the search is running. It must be 8-bit or 32-bit floating-point.
    .   @param templ Searched template. It must be not greater than the source image and have the same
    .   data type.
    .   @param result Map of comparison results. It must be single-channel 32-bit floating-point. If image
    .   is \f$W \times H\f$ and templ is \f$w \times h\f$ , then result is \f$(W-w+1) \times (H-h+1)\f$ .
    .   @param method Parameter specifying the comparison method, see #TemplateMatchModes
    .   @param mask Mask of searched template. It must have the same datatype and size with templ. It is
    .   not set by default. Currently, only the #TM_SQDIFF and #TM_CCORR_NORMED methods are supported.
    """
    pass
cv2.minMaxLoc()函數說明
def minMaxLoc(src, mask=None): # real signature unknown; restored from __doc__
    """
    minMaxLoc(src[, mask]) -> minVal, maxVal, minLoc, maxLoc
    .   @brief Finds the global minimum and maximum in an array.
    .   
    .   The function cv::minMaxLoc finds the minimum and maximum element values and their positions. The
    .   extremums are searched across the whole array or, if mask is not an empty array, in the specified
    .   array region.
    .   
    .   The function do not work with multi-channel arrays. If you need to find minimum or maximum
    .   elements across all the channels, use Mat::reshape first to reinterpret the array as
    .   single-channel. Or you may extract the particular channel using either extractImageCOI , or
    .   mixChannels , or split .
    .   @param src input single-channel array.
    .   @param minVal pointer to the returned minimum value; NULL is used if not required.
    .   @param maxVal pointer to the returned maximum value; NULL is used if not required.
    .   @param minLoc pointer to the returned minimum location (in 2D case); NULL is used if not required.
    .   @param maxLoc pointer to the returned maximum location (in 2D case); NULL is used if not required.
    .   @param mask optional mask used to select a sub-array.
    .   @sa max, min, compare, inRange, extractImageCOI, mixChannels, split, Mat::reshape
    """
    pass
使用OpenCV提供的6種算法模板匹配算法種,哪一種的算法效果相對不是很理想呢?

答案:TM_CCORR

簡答題

自己找一張或者使用課程提供的圖片,進行模板的匹配。如果是自己找的照片,需要製作好模板哦。

import cv2
import numpy as np
from matplotlib import pyplot as plt

plt.close('all')

src = cv2.imread('cxk.jpg', 1)
if src is None:
    print('Could not open or find the image')
    exit(0)
print(src.shape)
cv2.imshow("ori", src)
imgGray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
template = cv2.imread('cxk_temp.png', 0)
if template is None:
    print('Could not open or find the template')
    exit(0)
print(template.shape)

h, w = template.shape[:2]
print("w = %d, h = %d" % (w, h))

res = cv2.matchTemplate(imgGray, template, cv2.TM_CCOEFF_NORMED)
threshold = 0.8

loc = np.where(res >= threshold)
for pt in zip(*loc[::-1]):
    cv2.rectangle(src, pt, (pt[0] + w, pt[1] + h), (255, 0, 0), 2)
cv2.imwrite('match_temp_res.png', src)
cv2.imshow('deteced points', src)
cv2.waitKey(0)
cv2.destroyAllWindows()

效果:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章