画像からテンプレート画像を探す(テンプレートマッチング)

テンプレート画像を与え 入力画像からそのテンプレート画像にマッチングした領域を探すことを テンプレートマッチングといいます。
OpenCvでは ImgprocクラスのmatchTemplateメソッドで この テンプレートマッチングを行います。

static void matchTemplate(Mat image, Mat templ, Mat result,int method)
Mat image :  テンプレートの探索対象となる画像.8ビットまたは32ビットの浮動小数点型。
Mat templ : 探索されるテンプレート.探索対象となる画像以下のサイズで,同じデータ型でなければいけません。
Mat result : 比較結果のマップ.シングルチャンネル,32ビット,浮動小数点型。
 image が(W,H)   で, templ が(w,h) とすると result は(W-w+1,H-h+1) となります。
int method : 比較手法の指定 Imgprocクラスの定数を指定します。
 TM_SQDIFF、TM_SQDIFF_NORMED、TM_CCORR、TM_CCORR_NORMED、TM_CCOEFF、TM_CCOEFF_NORMED
 詳しくは OpenCv2.2 C++リファレンスを参照してください。数式だらけで何のコッチャ(笑い)

この関数による比較の後、Coreクラスの関数 minMaxLoc() を用いて,大域的最小値( CV_TM_SQDIFF の場合)あるいは大域的最大値( CV_TM_CCORR や CV_TM_CCOEFF の場合)を検出することでベストマッチを得ることができます。

static Core.MinMaxLocResult minMaxLoc(Mat src) 
static Core.MinMaxLocResult minMaxLoc(Mat src, Mat mask)

 実行結果 
//入力画像
Bitmap src = BitmapFactory.decodeFile(path);
Bitmap src1 = src.copy(Bitmap.Config.ARGB_8888, true);
Mat image = android.BitmapToMat(src1);
//テンプレート画像
src = BitmapFactory.decodeFile(path2);
Bitmap src2 = src.copy(Bitmap.Config.ARGB_8888, true);
Mat templ = android.BitmapToMat(src2);
//テンプレートマッチング
Mat result = new Mat();
Imgproc.matchTemplate(image, templ, result, Imgproc.TM_CCOEFF_NORMED);
Core.MinMaxLocResult maxr = Core.minMaxLoc(result);
//マッチング結果の表示
Point maxp = maxr.maxLoc;
Point pt2 = new Point(maxp.x + templ.width(), maxp.y + templ.height());
Mat dst = image.clone();
Core.rectangle(dst, maxp, pt2, new Scalar(255,0,0), 2);

実行結果は下図
上段:入力画像
中段:テンプレート画像
下段:マッチング結果

Imgproc.matchTemplate(image, templ, result, Imgproc.TM_CCOEFF_NORMED);のmethodを変えてみました。
TM_CCOEFF : TM_CCOEFF_NORMEDと全く同じ結果
TM_SQDIFF、TM_SQDIFF_NORMED
:
Point maxp = maxr.maxLoc; を Point maxp = maxr.minLoc;
 とすることでTM_CCOEFF_NORMEDと全く同じ結果
TM_CCORR、TM_CCORR_NORMED :
TM_CCOEFF_NORMEDと全く同じ結果をどうすれば得られるかはわかりませんでした。

 by Android2.2 with OpenCv 2.3.1 for Android
スポンサーリンク
Rectangle大広告
Rectangle大広告

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

コメント

  1. 葉っぱ より:

    ありがとう。
    参考になりました。ありがとうございます。