PR

【Python】CV2でテンプレートマッチング(画像検出)

コラム
スポンサーリンク

テンプレートマッチングとは、座標同士の類似度を求める手法です。
それにより画像の中から画像を検索することができます。
類似度を求めているということは、完全一致の画像の他、類似の画像でも発見できるのかどうか、ウォーリーを探せを使って試してみました。

テンプレートマッチングでウォーリーを探してみる

OpenCV(cv2)をcondaでインストール

私の環境はanacondaを使用しているおり、下記のようにインストールしました。

conda install -c conda-forge opencv

テンプレート検索

import cv2
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
image = cv2.imread(r".\imagesFolder\4.jpg") #検索先画像のファイルパスを指定
template = cv2.imread(r".\imagesFolder\4-w.jpg") #検索元画像ファイルパスを指定
height, width, channels = template.shape

CCOEFF、CCORR、SQDIFFを使ってみます。

methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCORR', 'cv2.TM_SQDIFF']

for m in methods:
    full_copy = image.copy()
    method = eval(m)

    res = cv2.matchTemplate(full_copy,template,method)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

    if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
        top_left = min_loc    
    else:
        top_left = max_loc
    bottom_right = (top_left[0] + width, top_left[1] + height)

    #発見したら赤囲み
    cv2.rectangle(full_copy,top_left, bottom_right, 255, 20)
    plt.rcParams["figure.figsize"] = [20,10.0] 
    plt.subplot(121)
    plt.imshow(res)
    plt.title('Result of Template Matching')
    plt.subplot(122)
    plt.imshow(full_copy)
    plt.title('Detected Point')
    plt.suptitle(m)
        
    plt.show()

検索結果

上記画像では右下の方に赤囲みが付いています。正しく発見されています。

上記画像では右上に赤囲みが付いています。
残念ながらこの類似度計算ではこの画像には不向きだったようです。

上記画像では右下の方に赤囲みが付いています。正しく発見されています。

全く一致する訳ではない画像で検索する

先ほどは左の画像で検索してみました。これは完全に検索対象の画像と一致します。
今度は右の画像で検索してみます。
人間目線では類似しているのでどういう結果になるか楽しみです。

完全に一致するわけではない画像でのテンプレートマッチング結果

上記画像では中央あたりに赤囲みが付いています。
残念ながら正しく検出されませんでした。

上記画像では中央あたりに赤囲みが付いています。
残念ながら正しく検出されませんでした。

上記画像では中央あたりに赤囲みが付いています。
残念ながら正しく検出されませんでした。

まとめ

完全一致の画像であれば用意されている検出方法で検出することができました。
ただしテストをして相性が良いかどうかは試す必要があります。

コメント

タイトルとURLをコピーしました