模板匹配算法(单图像模板匹配和基于模板匹配的目标跟踪)

1.模板匹配opencv函数

链接:http://www.opencv.org.cn/opencvdoc/2.3.2/html/modules/imgproc/doc/object_detection.html?highlight=matchtemplate#cv.MatchTemplate

 

matchTemplate(InputArray image, InputArray temp, OutputArray result, int method)

Parameters:
  • image – Image where the search is running. It must be 8-bit or 32-bit floating-point.
  • templ – Searched template. It must be not greater than the source image and have the same data type.
  • result – Map of comparison results. It must be single-channel 32-bit floating-point. If image is 模板匹配算法(单图像模板匹配和基于模板匹配的目标跟踪)and templ is 模板匹配算法(单图像模板匹配和基于模板匹配的目标跟踪) , then result is 模板匹配算法(单图像模板匹配和基于模板匹配的目标跟踪) .
  • method – Parameter specifying the comparison method (see below).

第一个参数为输入源图像,第二个参数为输入模板图像,第三个参数为匹配结果,记录在源图像上滑动窗口和模板的相似程度,第四个参数为匹配方法。

匹配方法:

CV_TM_SQDIEF平方差匹配法,最好匹配为0,值越大匹配越差

CV_TM_SQDIEF_NORMED归一化平方差匹配法

CV_TM_CCORR相关匹配法,采用乘法操作,数值越大表明匹配越好

CV_TM_CCORR_NORMED归一化相关匹配法

CV_TM_CCOEFF相关系数匹配法,最好匹配为1,最差为-1

CV_TM_CCOEFF_NORMED归一化相关系数匹配法

各匹配方法原理见以上链接。

 

链接:http://www.opencv.org.cn/opencvdoc/2.3.2/html/modules/core/doc/operations_on_arrays.html?highlight=minmaxloc#cv.MinMaxLoc

 

minMaxLoc(InputArray src, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, InputArraymask=noArray())

Parameters:
  • src – Source single-channel array.
  • minVal – Pointer to the returned minimum value. NULL is used if not required.
  • maxVal – Pointer to the returned maximum value. NULL is used if not required.
  • minLoc – Pointer to the returned minimum location (in 2D case). NULL is used if not required.
  • maxLoc – Pointer to the returned maximum location (in 2D case). NULL is used if not required.
  • mask – Optional mask used to select a sub-array.

寻找矩阵中最大最小值以及对应坐标。

2.单图像模板匹配

原图:

模板匹配算法(单图像模板匹配和基于模板匹配的目标跟踪)

模板图像:

模板匹配算法(单图像模板匹配和基于模板匹配的目标跟踪)

 

代码如下:

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include "cxcore.h"

using namespace std;
using namespace cv;

int _tmain(int argc, _TCHAR* argv[])
{
	Mat img,templ,result;
	img = imread("1.jpg");
	templ = imread("2.jpg");

	int result_cols = img.cols - templ.cols + 1;
	int result_rows = img.rows - templ.rows + 1;
	result.create(result_cols, result_rows, CV_32FC1);

	matchTemplate(img, templ, result, CV_TM_SQDIFF_NORMED);//CV_TM_SQDIFF_NORMED CV_TM_SQDIFF
	normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());

	double minVal;
	double maxVal;
	Point minLoc;
	Point maxLoc;
	Point matchLoc;

	minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());

	matchLoc = minLoc;

	rectangle(img, matchLoc, Point(matchLoc.x + templ.cols, matchLoc.y + templ.rows), Scalar(0,255,0), 2, 8, 0);

	imshow("img", img);
	waitKey(0);

	return 0;
}


效果如下:

模板匹配算法(单图像模板匹配和基于模板匹配的目标跟踪)

模板匹配算法(单图像模板匹配和基于模板匹配的目标跟踪)

 

3.基于模板匹配的目标跟踪

由于采用鼠标画矩形框的方式进行模板图像的提取,所以对鼠标响应函数进行说明。

 

cvSetMouseCallback(const char* name, CvMouseCallback onMouse, void* param=NULL )

 

Parameters:

第一个参数为使用窗口名,第二个为onMouse鼠标消息消息处理函数,第三个为传给鼠标消息的任定参数。

这里添加onMouse函数如下:

void onMouse(int event,int x,int y,int flags,void*param)//事件回传代号,坐标,代号,Mouse事件的代号名称
{
	if (pause)
	{
		switch (event)
		{
		case CV_EVENT_MOUSEMOVE:
			if (drawbox){
				box.width = x - box.x;
				box.height = y - box.y;
			}
			break;
		case CV_EVENT_LBUTTONDOWN:
			drawbox = true;
			box = Rect(x, y, 0, 0);
			break;
		case CV_EVENT_LBUTTONUP:
			drawbox = false;
			if (box.width < 0){
				box.x += box.width;
				box.width *= -1;
			}
			if (box.height < 0){
				box.y += box.height;
				box.height *= -1;
			}

			cvtColor(img,imggray,CV_RGB2GRAY);
			templ = imggray(box);
			tracking = true;	
			rectangle(frame, box, Scalar(0, 255, 0), 3);
			imshow("ORI", frame);	
			imshow("Templ", templ);

			break;
		}
	}
}

Event:

 #define CV_EVENT_MOUSEMOVE 0                    滑動 

#define CV_EVENT_LBUTTONDOWN 1              左鍵點擊 

#define CV_EVENT_RBUTTONDOWN 2             右鍵點擊

 #define CV_EVENT_MBUTTONDOWN 3            中鍵點擊 

#define CV_EVENT_LBUTTONUP 4                     左鍵放開 

#define CV_EVENT_RBUTTONUP 5                    右鍵放開 

#define CV_EVENT_MBUTTONUP 6                    中鍵放開 

#define CV_EVENT_LBUTTONDBLCLK 7           左鍵雙擊

 #define CV_EVENT_RBUTTONDBLCLK 8         右鍵雙擊

 #define CV_EVENT_MBUTTONDBLCLK 9         中鍵雙擊

 

flags: 
#define CV_EVENT_FLAG_LBUTTON 1             左鍵拖曳

 #define CV_EVENT_FLAG_RBUTTON 2           右鍵拖曳

 #define CV_EVENT_FLAG_MBUTTON 4           中鍵拖曳 

#define CV_EVENT_FLAG_CTRLKEY 8            (8~15)按Ctrl不放事件

 #define CV_EVENT_FLAG_SHIFTKEY 16        (16~31)按Shift不放事件

 #define CV_EVENT_FLAG_ALTKEY 32            (32~39)按Alt不放事件

 

模板匹配跟踪函数如下:

void track(Mat gray, Mat &templ, Rect &box)
{
	double minVal;
	double maxVal;
	Point minLoc;
	Point maxLoc;
	matchTemplate(gray, templ, result, CV_TM_SQDIFF);
	minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());
	matchLoc = minLoc;
	rectangle(gray, matchLoc, Point(matchLoc.x + templ.cols, matchLoc.y + templ.rows), Scalar(0,0,255), 2, 8, 0);
}


 

GIF效果如下:

模板匹配算法(单图像模板匹配和基于模板匹配的目标跟踪)