文档章节

最简单的目标跟踪(模版匹配)

moki_oschina
 moki_oschina
发布于 2016/11/25 11:17
字数 991
阅读 48
收藏 2

一、概述

       目标跟踪是计算机视觉领域的一个重要分支。研究的人很多,近几年也出现了很多很多的算法。大家看看淋漓满目的paper就知道了。但在这里,我们也聚焦下比较简单的算法,看看它的优势在哪里。毕竟有时候简单就是一种美。

       在这里我们一起来欣赏下“模板匹配”这个简单点的跟踪算法。它的思想很简单,我们把要跟踪的目标保存好,然后在每一帧来临的时候,我们在整个图像中寻找与这个目标最相似的,我们就相信这个就是目标了。那如何判断相似呢?就用到了一些相关性的东西了,这个在我之前的一篇博文里面介绍过,大家可以参考下:

       模板匹配中差值的平方和(SSD)与互相关准则的关系

http://blog.csdn.net/zouxy09/article/details/8549743

       然后为了适应目标的变化,我们就需要随时更新我们要跟踪的目标。换句话来说,在跟踪t帧的时候,也就是在第t帧寻找目标的时候,是与t-1帧中我们找到的目标来进行比较的。这样目标的外观变化就会及时的更新。这个就叫做在线跟踪方法。当然了,这个策略会导致跟踪漂移的问题,这就是近几年很多跟踪算法关注的重要问题之一了。

 

二、代码实现

       我的代码是基于VS2010+ OpenCV2.4.2的。代码可以读入视频,也可以读摄像头,两者的选择只需要在代码中稍微修改即可。对于视频来说,运行会先显示第一帧,然后我们用鼠标框选要跟踪的目标,然后跟踪器开始跟踪每一帧。对摄像头来说,就会一直采集图像,然后我们用鼠标框选要跟踪的目标,接着跟踪器开始跟踪后面的每一帧。具体代码如下:

simpleTracker.cpp

// Object tracking algorithm using matchTemplate
// Author : zouxy
// Date   : 2013-10-28
// HomePage : http://blog.csdn.net/zouxy09
// Email  : zouxy09@qq.com

#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

// Global variables
Rect box;
bool drawing_box = false;
bool gotBB = false;

// bounding box mouse callback
void mouseHandler(int event, int x, int y, int flags, void *param){
  switch( event ){
  case CV_EVENT_MOUSEMOVE:
    if (drawing_box){
        box.width = x-box.x;
        box.height = y-box.y;
    }
    break;
  case CV_EVENT_LBUTTONDOWN:
    drawing_box = true;
    box = Rect( x, y, 0, 0 );
    break;
  case CV_EVENT_LBUTTONUP:
    drawing_box = false;
    if( box.width < 0 ){
        box.x += box.width;
        box.width *= -1;
    }
    if( box.height < 0 ){
        box.y += box.height;
        box.height *= -1;
    }
    gotBB = true;
    break;
  }
}


// tracker: get search patches around the last tracking box,
// and find the most similar one
void tracking(Mat frame, Mat &model, Rect &trackBox)
{
	Mat gray;
	cvtColor(frame, gray, CV_RGB2GRAY);

	Rect searchWindow;
	searchWindow.width = trackBox.width * 3;
	searchWindow.height = trackBox.height * 3;
	searchWindow.x = trackBox.x + trackBox.width * 0.5 - searchWindow.width * 0.5;
	searchWindow.y = trackBox.y + trackBox.height * 0.5 - searchWindow.height * 0.5;
	searchWindow &= Rect(0, 0, frame.cols, frame.rows);

	Mat similarity;
	matchTemplate(gray(searchWindow), model, similarity, CV_TM_CCOEFF_NORMED); 

	double mag_r;
	Point point;
	minMaxLoc(similarity, 0, &mag_r, 0, &point);
	trackBox.x = point.x + searchWindow.x;
	trackBox.y = point.y + searchWindow.y;
	model = gray(trackBox);
}

int main(int argc, char * argv[])
{
	VideoCapture capture;
	capture.open("david.mpg");
	bool fromfile = true;
	//Init camera
	if (!capture.isOpened())
	{
		cout << "capture device failed to open!" << endl;
		return -1;
	}
	//Register mouse callback to draw the bounding box
	cvNamedWindow("Tracker", CV_WINDOW_AUTOSIZE);
	cvSetMouseCallback("Tracker", mouseHandler, NULL ); 

	Mat frame, model;
	capture >> frame;
	while(!gotBB)
	{
		if (!fromfile)
			capture >> frame;

		imshow("Tracker", frame);
		if (cvWaitKey(20) == 'q')
			return 1;
	}
	//Remove callback
	cvSetMouseCallback("Tracker", NULL, NULL ); 
	
	Mat gray;
	cvtColor(frame, gray, CV_RGB2GRAY); 
	model = gray(box);

	int frameCount = 0;

	while (1)
	{
		capture >> frame;
		if (frame.empty())
			return -1;
		double t = (double)cvGetTickCount();
		frameCount++;

		// tracking
		tracking(frame, model, box);	

		// show
		stringstream buf;
		buf << frameCount;
		string num = buf.str();
		putText(frame, num, Point(20, 20), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255), 3);
		rectangle(frame, box, Scalar(0, 0, 255), 3);
		imshow("Tracker", frame);


		t = (double)cvGetTickCount() - t;
		cout << "cost time: " << t / ((double)cvGetTickFrequency()*1000.) << endl;

		if ( cvWaitKey(1) == 27 )
			break;
	}

	return 0;
}

三、结果

       我们对在目标跟踪领域一个benchmark的视频-david来测试下代码的效果。如下图所以,每帧的帧号在右上角所示。这个视频的光照变化是挺大的,但是简单的模板匹配方法还是可以挺有效的进行跟踪的,而且速度很快,在这个视频中,只花费了1ms左右(耗时的长度与目标框的大小和机器的性能有关)。

 

 

 

 

 

 

 

 

 

 

 

本文转载自:http://www.cnblogs.com/ywsoftware/p/4434306.html

moki_oschina
粉丝 26
博文 202
码字总数 44864
作品 0
成都
程序员
私信 提问
Visual Tracking via Adaptive Structural Local Sparse Appearance Model

Visual Tracking via Adaptive Structural Local Sparse Appearance Model 使用自适应的结构化局部外观模型的视觉跟踪 Abstract——摘要 Sparse representation has been applied to visual......

Quincuntial
2016/02/03
0
0
Robust Object Tracking via Sparsity-based Collaborative Model

Robust Object Tracking via Sparsity-based Collaborative Model 基于稀疏性协同模型的鲁棒目标跟踪 Abstract——摘要 In this paper we propose a robust object tracking algorithm usin......

Quincuntial
2016/02/03
0
0
高斯反向投影实现检测图像中的特定物

regionproposalcat.png 高斯反向投影 在图像处理中,我们通常需要设置感兴趣的区域(ROI,region of interest),来简化我们的工作。也就是从图像中选择的一个图像区域,这个区域是我们图像分析...

Tony沈哲
2017/08/14
0
0
近几年目标跟踪算法发展综述(下)

2016年 VOT2016【Index】今年算法比赛结果没什么特别大的意外,CNN和结合深度特征的算法都排名靠前,没毛病。今年你知道主办方干了一件大好事,就是把所能搜集到的算法代码都给公布了,良心啊...

crazyice521
2017/04/19
0
0
分享 | 带来全新交互体验的『支付宝AR』技术大解密

小蚂蚁说: AR是一种新颖的交互方式,与传统交互方式相比,可以让用户更深入地参与互动,给用户带来新体验。 而春节期间,支付宝的「扫福得福」活动也异常火爆,支付宝将AR与游戏、红包相结合...

兔子酱
2018/04/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

利用mybatis generator生成实体类、Mapper接口以及对应的XML文件

项目中通常会遇到数据的持久化,如果是采用mybatis的orm,就会涉及到生成xml的问题,刚好mybatis官网提供了这么个插件MyBatis Generator,效果简直是棒呆。 1. 首先需要在build.gradle文件中...

啊哈关关
今天
2
0
SpringSocial相关的知识点

使用SprigSocial开发第三方登录 核心类 ServiceProvider(AbstractOauth2ServiceProvider):主要负责实现server提供商(例如QQ,微信等共有的东西),默认实现类是AbstractOauth2ServiceProvider...

chendom
今天
1
0
Java并发之AQS详解

一、概述   谈到并发,不得不谈ReentrantLock;而谈到ReentrantLock,不得不谈AbstractQueuedSynchronizer(AQS)!   类如其名,抽象的队列式的同步器,AQS定义了一套多线程访问共享资源...

群星纪元
昨天
2
0
Fabric-sdk-java最新教程

Fabric Java SDK是Fabric区块链官方提供的用于Java应用开发的SDK,全称为Fabric-sdk-java,网上可用资料不多,本文列出了精心整理的针对Fabric Java SDK的最新精选教程。 如果希望快速掌握F...

汇智网教程
昨天
2
0
react 子组件监听props 变化

componentWillReceiveProps //已经被废弃 getDerivedStateFromProps// 推荐使用//如果条件不存在必须要返回null static getDerivedStateFromProps(props, current_stat...

一箭落旄头
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部