概要
OpenCV でテンプレートマッチングを行う方法について解説します。
テンプレートマッチング
検出対象の物体が映るテンプレート画像を用意します。
入力画像に対して、テンプレート画像と同じ大きさの検索窓を左上から右下にかけてスライドさせながら移動させます。
移動する検索窓の各位置において、「入力画像の検索窓の範囲」と「テンプレート画像」の類似度を計算します。
検索窓のすべての位置で計算された類似度が最終的な出力結果になります。
cv2.matchTemplate
公式リファレンス: cv2.matchTemplate
引数
名前 |
型 |
デフォルト値 |
image |
ndarray |
|
入力画像 |
templ |
ndarray |
|
テンプレート画像 |
method |
TemplateMatchModes |
|
類似度の計算方法 |
返り値
名前 |
説明 |
result |
検索窓の各位置での類似度 |
サンプルコード
入力画像からテンプレート画像の ❓ ボックスを探します。
sample1.jpg
入力画像
template.jpg
テンプレート画像
result について
返り値 result
は、検索窓の各位置でのテンプレート画像との類似度を表す 2 次元配列です。
入力画像の大きさを (W,H)、テンプレート画像の大きさを (w,h)、検索窓の左上の点を (x,y) としたとき、
検索窓は (x,y)∈(W−w+1,H−h+1) の範囲でスライドします。
result[y, x]
は検索窓が位置 (x, y)
から (x+w,y+h) にあるときの類似度の値になります。
result の解釈
img.shape (380, 694, 3)
template.shape (29, 33, 3)
result.shape (352, 662)
matplotlib で類似度のヒートマップを描画します。黄色のところは類似度が高いことを意味します。
類似度が最も高い場所を探す
テンプレート画像が最もマッチする位置を探すには、cv2.minMaxLoc()
を使用します。
この関数は、配列の最大値、最小値およびそれぞれの位置を返します。
max value: 0.997153639793396, position: (390, 124)
類似度が閾値以上の場所を探す
類似度が最も高い場所を探した場合、2 つある ❓ ブロックのうち 1 つしか検出されません。
類似度が一定以上の場所はすべて検出するように変更するには、以下のようにします。
類似度の計算方法
method
引数で指定できる類似度の計算方法には以下があります。とくに拘りがなければ、cv2.CCOEFF_NORMED
にしておくとよいでしょう。
入力画像を I、テンプレート画像を T、出力結果を result とします。
検索窓が位置 (x,y) にあり、入力画像の検索窓の領域およびテンプレート画像の画素を 1 次元配列としたものを uxy,vxy としたとき、類似度の計算はこの 2 つのベクトルの類似度を計算することに他なりません。
cv2.TM_SQDIFF
類似度を二乗差 (sum of square difference, SQDIFF) で計算します。
result(x,y)=i,j∑(T(i,j)–I(x+i,y+j))2=∥uxy–vxy∥2cv2.TM_SQDIFF_NORMED
類似度を正規化二乗差 (normalized square difference) で計算します。
result(x,y)=∑i,jT(i,j)2∑i,jI(x+i,y+j)2∑i,j(T(i,j)–I(x+i,y+j))2=∥uxy∥∥vxy∥∥uxy–vxy∥2cv2.TM_CCORR
類似度を相互相関 (cross correlation, CCORR) で計算します。
result(x,y)=i,j∑T(i,j)I(x+i,y+j)=uxy⋅vxycv2.TM_CCORR_NORMED
類似度を正規化相互相関 (normalized cross correlation) で計算します。
これはベクトル uxy,vxy のなす角を θ としたときの cosθ であり、コサイン類似度と呼ばれます。
出力値は [−1,1] の範囲になります。
result(x,y)=∑i,jT(i,j)2∑i,jI(x+i,y+j)2∑i,jT(i,j)I(x+i,y+j)]=∥uxy∥∥vxy∥uxy⋅vxycv2.TM_CCOEFF
類似度を相関係数 (correlation coefficient, COOEFF) で計算します。
result(x,y)=i,j∑(T′(i,j)⋅I′(x+i,y+j))=(uxy–uˉxy)⋅(vxy–vˉxy)ただし、
T′(i,j)I′(x+i,y+j)=T(i,j)–wh1i’,j’∑T(i’,j’)=I(x+i,y+j)–wh1i’,j’∑I(x+i’,y+j’)cv2.TM_CCOEFF_NORMED
類似度を正規化相関係数 (normalized correlation coefficient) で計算します。
出力値は [−1,1] の範囲になります。
result(x,y)=∑i,jT′(i,j)2⋅∑i,jI′(x+i,y+j)2∑i,j(T′(i,j)⋅I′(x+i,y+j))=∥uxy–uˉxy∥∥vxy–vˉxy∥(uxy–uˉxy)⋅(vxy–vˉxy)各 method のよる結果の違い
コメント