模板匹配就是图像搜索的的一个过程,只不过是找到模板在原图像中最为相似的一块

OpenCV提供了模板匹配的函数

void matchTemplate(InputArray image, InputArray templ, OutputArray result, int method)
image参数:代表原图像;

templ参数:模板;

result参数:输出的结果,可以说这是一幅相似度图像;

method参数:相似度的度量方式。

                        差值平方和匹配 0 CV_TM_SQDIFF
                        标准化差值平方和匹配 1 CV_TM_SQDIFF_NORMED
                        相关匹配 2 CV_TM_CCORR
                        标准相关匹配 3 CV_TM_CCORR_NORMED
                        相关匹配 4 CV_TM_CCOEFF
                        标准相关匹配 5 CV_TM_CCOEFF_NORMED


具体该函数详解参考官方文档

官方手册matchTemplate函数详解

下面贴出一段改编自官方文档的代码

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <stdlib.h>
using namespace cv;
using namespace std;

//全局变量
Mat img; Mat templ; Mat result;
char *image_window ="Source Image";
char *result_window = "Result Image";
char *template_window = "Template Image";
int match_method;//滑动条的值对应不同的相似度度量方法
int max_trackBar = 5;//滑动条最大值
void MatchMethod(int,void *);//滑动条的回调函数

int main()
{
	img = imread("number.png", 0);
	templ = imread("num_templ.png", 0);
	namedWindow(image_window, CV_WINDOW_AUTOSIZE);
	namedWindow(result_window, CV_WINDOW_AUTOSIZE);
	namedWindow(template_window, CV_WINDOW_AUTOSIZE);
	char *trackBar_label = "Method:";
	createTrackbar(trackBar_label, image_window, &match_method, max_trackBar, MatchMethod);//创建滑动条
       MatchMethod(0, 0);
	waitKey(0);
	cvDestroyAllWindows();
	return 0;
}

void MatchMethod(int, void *)
{
	Mat display_img;
        Mat result_copy;
       img.copyTo(display_img);
        
	int result_rows = img.rows - templ.rows + 1;
	int result_cols = img.cols - templ.cols + 1;
	
	result.create(result_rows, result_cols, CV_32FC1);
	matchTemplate(img, templ,result_copy, match_method);//调用模板匹配函数
	normalize(result_copy, result, 1, 0, NORM_MINMAX,-1,Mat());//归一化操作

	double minVal, maxVal;
	Point minLoc, maxLoc, matchLoc;
	minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc,Mat());//寻找result图像中最大值,最小值的坐标
	if (match_method==CV_TM_SQDIFF||match_method==CV_TM_SQDIFF_NORMED)//这两种方式是取最小值
	{
		matchLoc = minLoc;
	} 
	else
	{
		matchLoc = maxLoc;
	}
        //标出模板在原图的位置
        rectangle(display_img, matchLoc, Point(matchLoc.x + templ.cols, matchLoc.y + templ.rows), Scalar::all(255), 2, 8);
	rectangle(result, matchLoc, Point(matchLoc.x + templ.cols, matchLoc.y + templ.rows), Scalar::all(0), 2, 8);
	imshow(image_window, display_img);
	imshow(result_window, result);
	imshow(template_window, templ);
	return;
}

选用的模板就是一个6的数字


可以从结果看出还是很好的框选出模板的位置,毕竟图像简单,下图是选用标准化差值平方和匹配的方式

d

我们看一下归一化的Result图


相似度图像效果非常好,标出了模板定位点,其余的都为白色。

再看一下其他相似度度量方式的结果,下图是相关匹配度量方式的结果

相似度图,可以看出最亮的一个点就是模板定位点