입력 영상에서 작은 크기의 부분 영상 위치를 찾아내고 싶은 경우에 주로 템플릿 매칭 기법을 사용한다. 여기서 템플릿은 찾고자 하는 대상이 되는 작은 크기의 영상을 의미한다. 템플릿 매칭은 작은 크기의 템플릿 영상을 입력 영상 전체 영역에 대해 이동하면서 가장 비슷한 위치를 수치적으로 찾아내는 방식이다.
템플릿 영상을 입력 영상 전체 영역에 대해 이동하면서 템플릿 영상과 입력 영상 부분 영상과의 유사도 또는 비유사도를 계산한다. 위의 b 그림에서 가장 밝은 픽셀 위치가 템플릿 영상과 가장 유사한 부분이다.
OpenCV 에서 matchTemplate() 함수를 사용하여 템플릿 매칭을 수행할 수 있다.
void matchTemplate(InputArray image, InputArray templ,
OutputArray result, int method, Inputarray mask =noArray());
image : 입력영상
templ : 템플릿 영상
result : 비교 결과를 저장할 행렬
method : 템플릿 매칭 비교 방법
mask : 찾고자 하는 템플릿의 마스크 영상
void template_matching() {
Mat img = imread("circuit.bmp", IMREAD_COLOR);
Mat templ = imread("crystal.bmp", IMREAD_COLOR);
if (img.empty() || templ.empty()) {
cerr << "Image load failed!" << endl;
return;
}
img = img + Scalar(50, 50, 50); //밝기증가
Mat noise(img.size(), CV_32SC3);
randn(noise, 0, 10);
add(img, noise, img, Mat(), CV_8UC3); //가우시안잡음추가
Mat res, res_norm;
matchTemplate(img, templ, res, TM_CCOEFF_NORMED);
normalize(res, res_norm, 0, 255, NORM_MINMAX, CV_8U); //정규화 후 res_norm 에 저장
double maxv;
Point maxloc;
minMaxLoc(res, 0, &maxv, 0, &maxloc);
cout << "maxv : " << maxv << endl;
rectangle(img, Rect(maxloc.x, maxloc.y, templ.cols, templ.rows), Scalar(0, 0, 255), 2);
imshow("templ", templ);
imshow("res_norm", res_norm);
imshow("img", img);
waitKey();
destroyAllWindows();
}
유사도 행렬