008 OpenCV matchTemplate テンプレートのマッチング

目次

1. 環境

2. テンプレートマッチングアルゴリズムの原理

3. コードのデモ


1. 環境

この記事の利用環境は以下の通りです。

  • ウィンドウズ10
  • Python 3.9.17
  • opencv-python 4.8.0.74

2. テンプレートマッチングアルゴリズムの原理

cv.matchTemplateは、テンプレートに一致する画像内の特徴を見つけるために使用される OpenCV ライブラリの関数です。その主な応用シナリオは、画像処理、コンピュータ ビジョン、パターン認識の分野です。

アルゴリズムの原理: cv.matchTemplateこの関数は、入力画像とテンプレート画像の間の類似性を計算することにより、最も一致する位置を見つけます。スライディング ウィンドウ方式を使用して、入力画像上でテンプレート画像を移動し、各ウィンドウ内のピクセル値の差を計算します。次に、選択したマッチング方法 (二乗差分、正規化二乗差分、相関係数など) に従って、差分に重み付けを行って合計し、マッチング スコア マトリックスを取得します。最後に、この関数は最大値と、スコア マトリックス内のその位置を最も一致する位置として返します。

関数API:

retval, result = cv2.matchTemplate(image, templ, method, mask)

パラメータの説明:

  • image: 入力画像。通常はグレースケール画像です。
  • templ: テンプレート イメージ。グレースケール イメージまたはカラー イメージを使用できます。
  • method: マッチング方法。一般的に使用される方法は次のとおりです。
    • cv2.TM_SQDIFF:二乗差分照合方式で、計算結果が小さいほど照合度が高くなります。
    • cv2.TM_SQDIFF_NORMED:正規化二乗差照合法で、計算結果が0に近いほど一致度が高くなります。
    • cv2.TM_CCORR: 相関係数一致法で、計算結果が1に近いほど一致度が高いことを示します。
    • cv2.TM_CCORR_NORMED: 正規化相関係数の一致法で、計算結果が1に近いほど一致度が高くなります。
    • cv2.TM_CCOEFF: 相関係数一致法で、計算結果が1に近いほど一致度が高いことを示します。
    • cv2.TM_CCOEFF_NORMED: 正規化相関係数の一致法で、計算結果が1に近いほど一致度が高くなります。
  • マスク: オプションのパラメータです。マスクは、パラメータ temp1 に作用するバイナリ イメージです。有効領域は、テンプレート マッチングの計算に参加します。

戻り値の説明:

  • result: マッチング結果行列。各要素は対応する位置のマッチング度を表します。
  • minVal, maxVal, minLoc, maxLoc:ベストマッチング位置の最小値、最大値、最小値位置、最大値位置。

以下は cv.matchTemplate() アルゴリズムの簡単な説明です:

  1. 前処理: まず、入力画像とテンプレート画像をグレースケール画像に変換します。これは、 cv.matchTemplate() アルゴリズムがグレースケール イメージのみをサポートしているためです。
  2. スライド テンプレート: アルゴリズムは入力画像上でテンプレートをスライドさせます。各位置 (左から右、上から下) に対して、一致スコアが計算されます。このスコアは、現在位置の画像とテンプレートの類似性に依存します。
  3. マッチング スコアの計算: 選択したマッチング方法に従って、現在位置のマッチング スコアを計算します。たとえば、正規化相関係数法が選択されている場合、アルゴリズムは入力画像と現在の位置のテンプレートの間の相関係数を計算します。正規化相関、二乗差分などの他の方法では、異なる計算方法が使用されます。
  4. 最も一致する位置を検索する: すべての位置の中で、アルゴリズムは一致スコアが最も高い位置を検索します。この位置がベストマッチング位置です。
  5. 結果を返す: 最後に、この関数は、一致するすべてのエリア情報を含む構造体を返します。この構造体には、各マッチング領域の座標、マッチングスコア、その他の情報が含まれています。

スライディング ウィンドウの制限により、テンプレートと画像の一部の領域が一致しない場合、これらの領域は一致スコアにカウントされないことに注意してください。これはマスク パラメータを使用して実現されます。マスクはテンプレートと同じサイズの 2 次元配列で、値は 0 または 1 です。マスク内の 1 の位置は試合スコアにカウントされますが、0 の位置はカウントされません。

全体的に、cv.matchTemplate() は、画像内でテンプレートに最も一致する領域を見つけるための強力なツールです。画像処理、コンピュータビジョン、パターン認識などの分野で広く使用されています。

3. コードのデモ

コードで必要な 3 つの画像は、lena_tmpl.jpg に示されています。以下は元の画像です。

tmpl.png、以下はテンプレート画像です。これは、元の画像内で類似した領域を見つけて、それを長方形で描画することを意味します。

Mask.png は、tmp1.png と同じサイズである必要があり、テンプレート計算プロセス中にテンプレート イメージ内のどの領域がテンプレート マッチングに使用されるかを示すために使用されるバイナリ イメージです。

from __future__ import print_function
import sys
import cv2 as cv

# 全局变量
use_mask = False
img = None
templ = None
mask = None
image_window = "Source Image"
result_window = "Result window"

match_method = 0
max_Trackbar = 5

def main():
    # 读取三张图
    global img
    global templ
    img = cv.imread('data/lena_tmpl.jpg', cv.IMREAD_COLOR) # 图片1
    templ = cv.imread('data/tmpl.png', cv.IMREAD_COLOR) # 图片2

    global use_mask
    use_mask = True
    global mask
    mask = cv.imread('data/mask.png', cv.IMREAD_COLOR ) # 图片3

    if ((img is None) or (templ is None) or (use_mask and (mask is None))):
        print('Can\'t read one of the images')
        return -1
    cv.namedWindow( image_window, cv.WINDOW_AUTOSIZE )
    cv.namedWindow( result_window, cv.WINDOW_AUTOSIZE )
    # 创建滑条
    trackbar_label = 'Method: \n 0: SQDIFF \n 1: SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n 4: TM COEFF \n 5: TM COEFF NORMED'
    cv.createTrackbar( trackbar_label, image_window, match_method, max_Trackbar, MatchingMethod )
    # 执行模板匹配
    MatchingMethod(match_method)
    cv.waitKey(0)
    return 0

def MatchingMethod(param):
    global match_method
    match_method = param
    img_display = img.copy()
    # 模板匹配
    method_accepts_mask = (cv.TM_SQDIFF == match_method or match_method == cv.TM_CCORR_NORMED)
    if (use_mask and method_accepts_mask):
        result = cv.matchTemplate(img, templ, match_method, None, mask)
    else:
        result = cv.matchTemplate(img, templ, match_method)
    # 将结果进行归一化到[0, 1]
    cv.normalize( result, result, 0, 1, cv.NORM_MINMAX, -1 )
    # 找到最佳匹配
    _minVal, _maxVal, minLoc, maxLoc = cv.minMaxLoc(result, None)
    # 得到的匹配位置,即:一个矩形框
    if (match_method == cv.TM_SQDIFF or match_method == cv.TM_SQDIFF_NORMED):
        matchLoc = minLoc
    else:
        matchLoc = maxLoc
    # 可视化
    cv.rectangle(img_display, matchLoc, (matchLoc[0] + templ.shape[0], matchLoc[1] + templ.shape[1]), (0,255,0), 2, 8, 0 )
    cv.rectangle(result, matchLoc, (matchLoc[0] + templ.shape[0], matchLoc[1] + templ.shape[1]), (0,0,255), 2, 8, 0 )
    cv.imshow(image_window, img_display)
    cv.imshow(result_window, result)
    pass
if __name__ == "__main__":
    main()

以下は、さまざまなアルゴリズムの動作効果です。どのアルゴリズムが悪いのかが一目でわかります。実際に試してみることもできます。

\n 0: SQDIFF

\n 1: SQDIFF

\n 2: TM CCORR

\n 3: TM CCORR

\n 4: TM COEFF

\n 5: TM COEFF

おすすめ

転載: blog.csdn.net/m0_72734364/article/details/134548276