テンプレートマッチングの比較

cvMatchTemplateを使ってテンプレートマッチングを行ってみる。

  • マッチングに利用できる相関関数
    • CV_TM_SQDIFF (最小値の座標がマッチング位置)
    • CV_TM_SQDIFF_NORMED
    • CV_TM_CCORR (最大値の座標がマッチング位置)
    • CV_TM_CCORR_NORMED
    • CV_TM_CCOEFF (最大値の座標がマッチング位置)
    • CV_TM_CCOEFF_NORMED

・入力画像(cover.jpg)

・テンプレート(safari.jpg)

ソースコード

#include <cv.h>
#include <highgui.h>
#include <stdio.h>

int main(void)
{
    IplImage *src = 0, *tmpl = 0;
	IplImage *ftmp[6];
	IplImage *copy_img[6];
	double min_value, max_value;
	CvPoint min_loc, max_loc;
	CvFont font;
	CvSize text_size;
	char file_name[256];
	char text[256];
		
	src = cvLoadImage("cover.jpg", CV_LOAD_IMAGE_COLOR);
	tmpl = cvLoadImage("safari.jpg", CV_LOAD_IMAGE_COLOR);

	if(src == 0 || tmpl == 0){
		return -1;
	}

	cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 1.0, 1.0, 0, 4, 4);
	
	for(int i=0;i<6;i++){
		copy_img[i] = cvCloneImage(src);
		ftmp[i] = cvCreateImage(cvSize(src->width - tmpl->width + 1, src->height - tmpl->height + 1), 32, 1);
	
		cvMatchTemplate(src, tmpl, ftmp[i], i);
		cvMinMaxLoc(ftmp[i], &min_value, &max_value, &min_loc, &max_loc, NULL);
		cvRectangle(copy_img[i], max_loc, cvPoint(max_loc.x + tmpl->width, max_loc.y + tmpl->height), CV_RGB(255, 0, 0), 3);

		switch(i){
			case 0:
				sprintf(text, "CV_TM_SQDIFF");
				break;
			case 1:
				sprintf(text, "CV_TM_SQDIFF_NORMED");
				break;
			case 2:
				sprintf(text, "CV_TM_CCORR");
				break;
			case 3:
				sprintf(text, "CV_TM_CCORR_NORMED");
				break;
			case 4:
				sprintf(text, "CV_TM_CCOEFF");
				break;
			case 5:
			sprintf(text, "CV_TM_CCOEFF_NORMED");
				break;
		}

		cvGetTextSize(text, &font, &text_size, 0);
		cvPutText(copy_img[i], text, cvPoint (10, text_size.height), &font, CV_RGB(255 , 0 , 0));

		sprintf(file_name, "tmp%2d.jpg", i);
		cvSaveImage(file_name, copy_img[i]);
	}

	return 0;

}

・実行結果

Learning OpenCVによるとシンプルなのがSquare Difference(CV_TM_SQDIFF)で、洗練されてるのがCorrelation Coefficient(CV_TM_CCOEFF)だそうです。