【图像处理】模板匹配视频跟踪c++

@转载请注明出处

模板匹配跟踪:

1.鼠标标记初始目标位置,并初始化模板
2.每一帧在上一帧匹配出来的位置附近搜索,可以加快速度。
3.加入丢失阈值判断,当丢失的时候不画波门。

主要应用opencv模板匹配api:

CV_EXPORTS_W void matchTemplate( InputArray image, InputArray templ,
                                 OutputArray result, int method );

完整代码如下:

/*created at 2019/7/22 0:20*/
#include <iostream>
#include <opencv2/opencv.hpp>

static cv::Rect roi;
void drawLine(cv::Mat src, cv::Rect& res);
static bool drawflag = false;

void setMouse(int event, int x, int y, int flag, void* param)
{
	cv::Mat* image = (cv::Mat*)param;
	cv::Point p1, p2;
	switch(event)
	{
		case CV_EVENT_LBUTTONDOWN:
			drawflag = true;
			roi.x = x;
			roi.y = y;
			break;
		case CV_EVENT_MOUSEMOVE:
			p1 = cv::Point(roi.x, roi.y);
			p2 = cv::Point (x, y);
			if(drawflag)
				cv::rectangle(*image, p1, p2, cv::Scalar(255,0,0));
			break;
		case CV_EVENT_LBUTTONUP:
			roi.width = x - roi.x;
			roi.height = y - roi.y;
			if(drawflag)
			{
				drawLine(*image, roi);
				std::cout << "get track init rect, x: " << roi.x << "y: " << roi.y \
						<< "w: " << roi.width << "h: " << roi.height << std::endl;
				drawflag = false;
			}
			break;
		default:
			break;
	}
}

cv::Mat bgr2gray(cv::Mat src)
{
	cv::Mat gray;
	if(src.channels() == 3)
		cv::cvtColor(src, gray, CV_BGR2GRAY);
	else
		src.copyTo(gray);
	return gray;
}
void drawLine(cv::Mat src, cv::Rect& res)
{
	res.x = (res.x < 0 ? 0 : res.x);
	res.y = (res.y < 0 ? 0 : res.y);
	res.width = (res.width > src.cols ? src.cols : res.width);
	res.height = (res.height > src.rows ? src.rows : res.height);
	if(res.x + res.width > src.cols)
		res.x = src.cols - res.width - 1;
	if(res.y + res.height > src.rows)
		res.y = src.rows - res.height - 1;
	cv::rectangle(src, res, cv::Scalar(255,0,0));
}

bool matchTracker(cv::Mat src, cv::Rect& res, cv::Mat model, int scale, float failed)
{
	double maxVal;
	cv::Point matchPoint;
	cv::Mat model_32F;
	cv::Mat searchWindow;
	cv::Rect search;
	cv::Mat similarity;
	//simple check
	assert(src.data != NULL);
	assert(src.type() == CV_8UC1);
	assert(model.rows <= src.rows);
	assert(model.cols <= src.cols);

	//search window
	search.width = scale * res.width;
	search.width = (search.width > src.cols ? src.cols : search.width);
	search.height = scale * res.height;
	search.height = (search.height > src.rows ? src.rows : search.height);

	search.x = res.x + 0.5 * res.width - 0.5 * search.width;	
	if(search.x + search.width > src.cols)
		search.x = src.cols - search.width - 1;
	search.x = search.x < 0 ? 0 : search.x;

	search.y = res.y + 0.5 * res.height - 0.5 * search.height;
	if(search.y + search.height > src.rows)
		search.y = src.rows - search.height - 1;
	search.y = search.y < 0 ? 0 : search.y;
	
	searchWindow = src(search);
	searchWindow.convertTo(searchWindow, CV_32F);

	model.convertTo(model_32F, CV_32F);

	cv::matchTemplate(searchWindow, model_32F, similarity, CV_TM_CCOEFF_NORMED);
	cv::minMaxLoc(similarity, NULL, &maxVal, NULL, &matchPoint);
	
	if(maxVal > failed)
	{
		res.x = search.x + matchPoint.x;
		res.y = search.y + matchPoint.y;
		return true;
	}	
	return false;
}

int main(int argc, char* argv[])
{
	cv::Mat frame, bgr;
	cv::VideoCapture cap;
	cv::Mat model;
	cv::Rect trkRes;
	bool flag = true;
	const char *path = "vtest.avi";
	int key = 0;
	std::string windowName = "tracking.jpg";
	
	assert(cap.open(path));
	while(cap.read(bgr))
	{
		frame = bgr2gray(bgr);
		
		if(flag)
		{
			cv::imshow(windowName, bgr);
			cv::Mat copy = bgr.clone();
			cv::setMouseCallback(windowName, setMouse, (void*)&copy);
			while(!(key == 32 || key == 27 || key == 13))
			{			
				cv::imshow(windowName, copy);
				if(drawflag)
					copy = bgr.clone();
				key = cv::waitKey(1);
			}
			model = frame(roi);
			trkRes = roi;
			flag = false;
			continue;
		}
		else
		{
			bool state = matchTracker(frame, trkRes, model, 4, 0.5f);
			if(state)
				drawLine(bgr, trkRes);
			else
				std::cout << "track lose..." << std::endl;
		}
		cv::imshow(windowName, bgr);
		cv::waitKey(20);
	}
	cap.release();
	return 0;
}

暂时未加入多尺度。下一版本加入。
待续。。。

发布了35 篇原创文章 · 获赞 13 · 访问量 6330

猜你喜欢

转载自blog.csdn.net/qq_35306281/article/details/96782972