目次
はじめに
PythonとOpenCVを使ってテンプレートマッチングを行う方法を実装しました。
また、画像を回転したときのマッチング結果も実験してみました。
ソースコードと計算結果を解説します。
テンプレートマッチングとは別に特徴点/特徴量を使ったマッチング手法や増分符号相関法といった手法もあります。
詳細はこちらの記事で解説しています。
動作環境
・PyCharm Community Edition 2018.3.1 x64
・OpenCV 3.4.5.20
テンプレートマッチングとは
入力画像に対してテンプレート画像をスライドさせながら、両者の類似度を計算し、類似度が最も高い位置を探すことが出来ます。
この手法は古くからから使われてきた画像マッチング手法です。
類似度計算方法にはいくつかあり、本記事では数式の詳細にはついては触れませんが、興味ある方はOpenCVの公式ドキュメントを参考にしてみてください。
OpenCVではこれらの手法が既に実装されており、関数を呼び出すだけですぐ試すことが出来ます。
ただし、この手法は画像の回転やスケール変化に弱いとされています。
実験
今回は相関係数マッチング手法(ZNCC)を使って、テンプレートマッチングしてみます。
またその際に入力画像を回転させたときの結果についても確認してみます。
ソースコード
ソースコードはこちらになります。
import cv2 def rotate_img(image, angle): height, width, dim = image.shape # center of rotation center = (int(width/2), int(height/2)) # set scale scale = 1.0 trans = cv2.getRotationMatrix2D(center, angle, scale) #affine convert rot_image = cv2.warpAffine(image, trans, (width, height)) return rot_image if __name__ == "__main__": # input image img = cv2.imread("./input.jpg") temp = cv2.imread("./temp.jpg") # convert gray scale image gray_temp = cv2.cvtColor(temp, cv2.COLOR_RGB2GRAY) # get template image width, height h, w = gray_temp.shape # rotation image min_angle = 0 max_angle = 90 step_angle = 20 for i in range(min_angle, max_angle, step_angle): rot_image = rotate_img(img, i) gray_rot_img = cv2.cvtColor(rot_image, cv2.COLOR_RGB2GRAY) # template matching match = cv2.matchTemplate(gray_rot_img, gray_temp, cv2.TM_CCOEFF_NORMED)#ZNCC min_value, max_value, min_pt, max_pt = cv2.minMaxLoc(match) pt = max_pt # output result cv2.rectangle(rot_image, (pt[0], pt[1] ), (pt[0] + w, pt[1] + h), (0,0,200), 3) cv2.imwrite("result" + str(i) + ".jpg", rot_image)
結果
出力画像を見てみると、40°回転までは何とか上手くマッチング出来ていましたが、60°と80°では誤検出していることがわかります。
画像の回転にしてはやはりロバスト性が良くないですね。
・入力画像
・出力画像(左から0°, 20°, 40°, 60°, 80°)
まとめ
今回は最も基本的な画像照合手法の一つであるテンプレートマッチング(ZNCC)について回転時のロバスト性について調べてみました。
更に深い勉強をしたい方は下記の書籍がおすすめです!
古くからあるベストセラー本の改訂版で、多くのエンジニアから支持されている良書です。
少しお値段は張りますが、それだけの価値は絶対にあります。
詳解 OpenCV 3 ―コンピュータビジョンライブラリを使った画像処理・認識
人気記事