您的位置:首页 > 运维架构

TLD(Tracking-Learning-Detection)算法学习与源码解析(四)之LKTracker源码分析

2014-03-05 17:59 411 查看
         本序列文章的目的是总结一下这段时间所学到的,主要分为以下几部分,本章是第四部分。

算法概述
runtld.cpp源码解析
tld.cpp源码解析
LKTracker(重点)
FerNNClassifier.cpp源码解析(重点)
6 tld_utils.cpp源码解析

LKTracker.cpp实现的就是跟踪模块了,其中有一个金字塔LK光流法跟踪的算法是直接用了库函数的,这里不展开讲。
跟踪器的作用:
在一个patch跟踪一些points在另一个pacth的位置,还要根据相似度和误差把一些点过滤掉,
就是只保留那些跟踪效果好的点。

#include <LKTracker.h>
using namespace cv;

LKTracker::LKTracker(){
term_criteria = TermCriteria( TermCriteria::COUNT+TermCriteria::EPS, 20, 0.03);
window_size = Size(4,4);
level = 5;
lambda = 0.5;
}

/**
*在一个patch跟踪一些points在另一个pacth的位置
*还要根据相似度和误差把一些点过滤掉
*/
bool LKTracker::trackf2f(const Mat& img1, const Mat& img2,vector<Point2f> &points1, vector<cv::Point2f> &points2){
//TODO!:implement c function cvCalcOpticalFlowPyrLK() or Faster tracking function
//Forward-Backward tracking
calcOpticalFlowPyrLK( img1,img2, points1, points2, status,similarity, window_size, level, term_criteria, lambda, 0);
calcOpticalFlowPyrLK( img2,img1, points2, pointsFB, FB_status,FB_error, window_size, level, term_criteria, lambda, 0);
//Compute the real FB-error
for( int i= 0; i<points1.size(); ++i ){
FB_error[i] = norm(pointsFB[i]-points1[i]);
}
//Filter out points with FB_error[i] > median(FB_error) && points with sim_error[i] > median(sim_error)
normCrossCorrelation(img1,img2,points1,points2);
return filterPts(points1,points2);
}
/**
* 一个点取周围10*10的小patch
* 用归一化相关系数的算法把两个patch的相似度算出来,作为两个点的相关性。
*/
void LKTracker::normCrossCorrelation(const Mat& img1,const Mat& img2, vector<Point2f>& points1, vector<Point2f>& points2) {
Mat rec0(10,10,CV_8U);
Mat rec1(10,10,CV_8U);
Mat res(1,1,CV_32F);

for (int i = 0; i < points1.size(); i++) {
if (status[i] == 1) {
getRectSubPix( img1, Size(10,10), points1[i],rec0 );
getRectSubPix( img2, Size(10,10), points2[i],rec1);
matchTemplate( rec0,rec1, res, CV_TM_CCOEFF_NORMED);
similarity[i] = ((float *)(res.data))[0];

} else {
similarity[i] = 0.0;
}
}
rec0.release();
rec1.release();
res.release();
}

/**
*根据误差和相似度,把一些不符合条件的点给去掉
*/
bool LKTracker::filterPts(vector<Point2f>& points1,vector<Point2f>& points2){
//Get Error Medians
simmed = median(similarity);
size_t i, k;
for( i=k = 0; i<points2.size(); ++i ){
if( !status[i])
continue;
if(similarity[i]> simmed){
points1[k] = points1[i];
points2[k] = points2[i];
FB_error[k] = FB_error[i];
k++;
}
}
if (k==0)
return false;
points1.resize(k);
points2.resize(k);
FB_error.resize(k);

fbmed = median(FB_error);
for( i=k = 0; i<points2.size(); ++i ){
if( !status[i])
continue;
if(FB_error[i] <= fbmed){
points1[k] = points1[i];
points2[k] = points2[i];
k++;
}
}
points1.resize(k);
points2.resize(k);
if (k>0)
return true;
else
return false;
}

/*
* old OpenCV style
void LKTracker::init(Mat img0, vector<Point2f> &points){
//Preallocate
//pyr1 = cvCreateImage(Size(img1.width+8,img1.height/3),IPL_DEPTH_32F,1);
//pyr2 = cvCreateImage(Size(img1.width+8,img1.height/3),IPL_DEPTH_32F,1);
//const int NUM_PTS = points.size();
//status = new char[NUM_PTS];
//track_error = new float[NUM_PTS];
//FB_error = new float[NUM_PTS];
}

void LKTracker::trackf2f(..){
cvCalcOpticalFlowPyrLK( &img1, &img2, pyr1, pyr1, points1, points2, points1.size(), window_size, level, status, track_error, term_criteria, CV_LKFLOW_INITIAL_GUESSES);
cvCalcOpticalFlowPyrLK( &img2, &img1, pyr2, pyr1, points2, pointsFB, points2.size(),window_size, level, 0, 0, term_criteria, CV_LKFLOW_INITIAL_GUESSES | CV_LKFLOW_PYR_A_READY | CV_LKFLOW_PYR_B_READY );
}
*/


注:

原作者是用matlab实现的,我分析的源码是其他大神用c++和opencv实现的,源码可以从
https://github.com/arthurv/OpenTLD或者https://github.com/alantrrs/OpenTLD下载
本序列参考了zouxy09同学的序列文章,在此表示感谢
http://blog.csdn.net/zouxy09/article/details/7893011
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  TLD 机器学习 opencv
相关文章推荐