テンプレートマッチングで類似画像を探す
OpenCVの物体検出手段の一つ、テンプレートマッチングを行います。画像とそこから一部切り出したテンプレート画像を用意します。元画像の中でテンプレート画像と一致する場所を検出します。
関連記事
画像のヒストグラムを比較し類似度を求める
AKAZE特徴量による画像マッチング
やること
- 画像を読み出しそこに含まれる、テンプレート画像の類似画像を探す
- 最も類似度の高い範囲を元画像に赤の矩形で重ね書きし別ウィンドウで表示する
- キー入力で表示用ウィンドウを破棄し終了
使った関数
- cv2.imread : 画像ファイルの読み出し
- cv2.matchTemplate : テンプレートマッチングの実行
- cv2.rectangle : 矩形の描画
- cv2.imshow : 画像を別ウィンドウに表示する
環境
準備
画像ファイルはフリー写真素材ぱくたそからダウンロードさせていただき、"kokushimusou.jpg"というファイル名で、この画像から一部分を切り抜いてファイル名'ton.jpg'としてjupyter notebookファイル(***.ipynb)と同じディレクトリに保存しました。
kokushimusou.jpg
ton.jpg
コード
import cv2 #OpenCVのインポート img = cv2.imread("kokushimusou.jpg") #画像を読み込む img_gray = cv2.imread("kokushimusou.jpg",0) #画像をグレースケールで読み込む template = cv2.imread("ton.jpg", 0) #テンプレート画像をグレースケールで読み込む width, height = template.shape[::-1] #テンプレート画像の幅、高さを取得 result = cv2.matchTemplate(img_gray, template, cv2.TM_CCORR_NORMED) #テンプレートマッチングの実行(比較方法cv2.TM_CCORR_NORMED) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result) #類似度が最小,最大となる画素の類似度、位置を調べ代入する top_left = max_loc #最も似ている領域を赤で囲う bottom_right = (top_left[0] + width, top_left[1] + height) #矩形の右下の座標計算 cv2.rectangle(img,top_left, bottom_right, (0,0,255), 2) #最も似ている領域を赤の矩形で囲う print(max_val) #最も似ている領域の類似度を表示 cv2.imshow("result",img) #別ウィンドウ"result"を開きmgを表示 cv2.waitKey(0) #キー入力待ち cv2.destroyAllWindows() #ウインドウを閉じる
実行結果
最も似ている領域の類似度が表示されます。
0.9999507069587708
また、最も似ている領域が赤の矩形で囲まれて表示されます。
テンプレートマッチングはテンプレートのサイズが合わない場合うまく働かないアルゴリズムのようです。
試しに縦2倍、横2倍に拡大したテンプレート画像でやってみます。
ton2x.jpg
実行結果
まったく関係ない場所が検出されます(その割には類似度が高いように見えますが)。
0.918712317943573
以下のサイトを参考にさせていただきました
OpenCV-Python Tutorials >> テンプレートマッチング