4_12_テンプレートマッチング-OpenCV中国語の公式ドキュメント
テンプレートマッチングを使用して画像内のオブジェクトを検索します-次の関数が表示されます:cv.matchTemplate()、cv.minMaxLoc()
要約
- テンプレートマッチングは、大きな画像内のテンプレート画像の場所を検索および検索するための方法です。
- OpenCVには関数**cv.matchTemplate**()が付属しています。テンプレート画像を入力画像上にスライドさせ(2D畳み込みの場合のように) 、テンプレートとテンプレート画像の下の入力画像パズルを比較します。
コンテンツ
仮説
テンプレートマッチングは、大きな画像内のテンプレート画像の場所を検索および検索するための方法です。この目的のために、OpenCVには関数** cv.matchTemplate **()が付属しています。テンプレート画像を入力画像上にスライドさせ(2D畳み込みの場合のように) 、テンプレートとテンプレート画像の下の入力画像パズルを比較します。OpenCVにはいくつかの比較方法が実装されています。(詳細については、ドキュメントを確認できます)。各ピクセルがそのピクセルの近傍がテンプレートとどの程度一致しているかを表すグレースケール画像を返します。
入力画像
(WxH)
のサイズがで、テンプレート画像(wxh)
のサイズがである場合、出力画像のサイズはになります(W-w + 1,H-h + 1)
。結果を取得したら、** cv.minMaxLoc **()関数を使用して、最大/最小がどこにあるかを見つけることができます。長方形の左上隅、および長方形(w,h)
の幅と高さにします。この長方形は、テンプレートの領域です。比較方法としてcv.TM_SQDIFFを使用する場合は、最小値が最適な一致を提供することに注意してください。
OpenCVでのテンプレートマッチング
例として、写真でメッシの顔を検索します。そこで、次のようなテンプレートを作成しました。
すべての比較方法を試して、結果を確認します。
import cv2 as cv import numpy as np from matplotlib import pyplot as plt img = cv.imread('messi5.jpg',0) img2 = img.copy() template = cv.imread('template.jpg',0) w, h = template.shape[::-1] # 列表中所有的6种比较方法 methods = ['cv.TM_CCOEFF', 'cv.TM_CCOEFF_NORMED', 'cv.TM_CCORR', 'cv.TM_CCORR_NORMED', 'cv.TM_SQDIFF', 'cv.TM_SQDIFF_NORMED'] for meth in methods: img = img2.copy() method = eval(meth) # 应用模板匹配 res = cv.matchTemplate(img,template,method) min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res) # 如果方法是TM_SQDIFF或TM_SQDIFF_NORMED,则取最小值 if method in [cv.TM_SQDIFF, cv.TM_SQDIFF_NORMED]: top_left = min_loc else: top_left = max_loc bottom_right = (top_left[0] + w, top_left[1] + h) cv.rectangle(img,top_left, bottom_right, 255, 2) plt.subplot(121),plt.imshow(res,cmap = 'gray') plt.title('Matching Result'), plt.xticks([]), plt.yticks([]) plt.subplot(122),plt.imshow(img,cmap = 'gray') plt.title('Detected Point'), plt.xticks([]), plt.yticks([]) plt.suptitle(meth) plt.show()
以下の結果を確認してください。
- cv.TM_CCOEFF
cv.TM_CCOEFF_NORMED
cv.TM_CCORR
cv.TM_CCORR_NORMED
cv.TM_SQDIFF
cv.TM_SQDIFF_NORMED
ご覧のとおり、**cv.TM_CCORR**を使用した結果は理想的ではありません。
複数のオブジェクトのテンプレートマッチング
前のセクションでは、画像に1回だけ表示されたメッシの顔を画像で検索しました。複数回出現するオブジェクトを検索していると仮定すると、** cv.minMaxLoc **()はすべての場所を提供するわけではありません。この場合、しきい値を使用します。したがって、この例では、有名なゲーム**マリオ**のスクリーンショットを使用して、その中のコインを見つけます。
import cv2 as cv import numpy as np from matplotlib import pyplot as plt img_rgb = cv.imread('mario.png') img_gray = cv.cvtColor(img_rgb, cv.COLOR_BGR2GRAY) template = cv.imread('mario_coin.png',0) w, h = template.shape[::-1] res = cv.matchTemplate(img_gray,template,cv.TM_CCOEFF_NORMED) threshold = 0.8 loc = np.where( res >= threshold) for pt in zip(*loc[::-1]): cv.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2) cv.imwrite('res.png',img_rgb)
結果: