不再犹豫了,先从代码开始研究吧。在研究前,解释一下TLD这个词,TLD= Tracking Learning Detection,中文就是,跟踪-学习-检测,按照zdenek给的说明,TLD算法是一种用于跟踪在非限制视频流(unconstrained video streams)中的未知目标(unknown objects)。感兴趣目标是由单帧中的边框(bounding box)定义。不论什么时候目标出现在视频中,TLD算法可以同时跟踪目标,学习目标的外观(appearance),并且检测目标。
在zdenek的网站上下载matlab代码,然后看它的安装说明
根据说明:
1.平台:Matlab R2010a,MS2010, win7(64bit)(本人的机器是64位),opencv2.2
2. 安装mex -setup ,然后编译mex files:compile.m(其实这样就是作者希望使用matlab来调用C/C++写的代码),关于matlab+vs2010可能出现的问题见链接。
3.在matlab命令行运行:run_TLD.m,然后就会看到如下画面:
4.使用自己的笔记本电脑摄像头进行跟踪
1.imaqhwinfo;
2.a=imaqhwinfo('winvideo'); a.DeviceInfo
3.initcamera.m
4.source.vid = videoinput('winvideo', 1,'YUY2_320x240');
5.打开run_TLD.m,设置camera为1,即opt.source = struct('camera',1, ...
6.运行run_TLD.m,之后划一个方框,即可跟踪目标。
既然代码已经跑通了,那就开始代码的研究之旅了。
在源代码中,compile.m文件的作用,主要是将lk.cpp ,tld.cpp,fern.cpp, linkagemex.cpp, bb_overlap.cpp, warp.cpp, distance.cpp,
转换为:lk.mexw64, fern.mexw64, linkagemex.mexw64, bb_overlap.mexw64,warp.mexw64, distance.mexw64
下面我们将一个一个的来分析:
tld.h文件:
//获得积分图像
void iimg(unsigned char *in, double *ii, int imH, int imW);
void iimg2(unsigned char *in, double *ii2, int imH, int imW);
double bbox_var_offset(double *ii,double *ii2, int *off);
fern.cpp文件:
//fern.cpp的如入口函数
//nlhs:输出参数个数;plhs:输出参数指针;nrhs:输入参数个数;prhs:输入参数指针
void mexFunction(int nlhs,mxArray *plhs[], int nrhs, const mxArray *prhs[])
{}
linkagemex.cpp文件:
//目的:创建一个层次聚类树
template<class TEMPL>
void mexLinkageTEMPLATE(
//左手边
//右手边
int nlhs, /* Number ofleft hand side (output) arguments */
mxArray *plhs[], /* Array of left handside (output) arguments */
int nrhs, /* Number ofright hand side (input) arguments */
const mxArray *prhs[],/* Array of right hand side (input)arguments */
int call_pdist,
TEMPL classDummy
){}
//主函数入口
void mexFunction( /* GATEWAY FUNCTION */
int nlhs, /* Number ofleft hand side (output) arguments */
mxArray *plhs[], /* Array of left handside (output) arguments */
int nrhs, /* Number ofright hand side (input) arguments */
const mxArray *prhs[] /* Array of right hand side (input)arguments */
)
{
...
/* call the TEMPLATE function */
//如何输入的第一个参数为double类型
if (mxIsDouble(prhs[0]))
//执行模板函数
mexLinkageTEMPLATE(nlhs,plhs,nrhs,prhs,(nrhs==3),(double)(1.0));
else
//如果不是double类型,single
mexLinkageTEMPLATE(nlhs,plhs,nrhs,prhs,(nrhs==3),(float )(1.0));
}
bb_overlap.cpp文件:
/边框盒子的重叠(两个盒子的四个角进行判断)
double bb_overlap(double *bb1, double *bb2) {}
void mexFunction(int nlhs,mxArray *plhs[], int nrhs, const mxArray *prhs[])
{}
warp.cpp文件:
设置感兴趣区域,并且转换为matlab格式的图像数据
//设置图像的感兴趣区域
voidwarp_image_roi(unsigned char *image, int w, int h, double *H,
double xmin, double xmax,double ymin, double ymax,
double fill, double*result)
//将图像转换为matlab表示的图像
mxArray*to_matlab(const double *image, int num_cols, int num_rows)
{}
//warp.cpp的输入口函数
void mexFunction(int nlhs, mxArray *plhs [], int nrhs, const mxArray *prhs [])
{ …
//转换为matlab类型的的图像数据输出
plhs[0]=to_matlab(result,(int)(xmax-xmin+1), (int)(ymax-ymin+1));
}
distance.cpp文件:
大概就是要计算相关性和欧几里得距离
//相关性
// correlation
double ccorr(double*f1,double *f2,int numDim) {}
//相关性归一化
// correlation normalized
double ccorr_normed(double*f1,double *f2,int numDim) {} //f1=[1,2,3], f2=[4,5,6] f1*f2
//欧几里得距离
// euclidean distance
double euclidean(double*f1,double *f2,int numDim) {} //向量f1=[1,2,3,2],向量f2=[4,5,6,7]→D(a,b)=sqrt((1-4)^2+(2-5)^2+..+(2-7)^2)
//distance.cpp的输入口函数
void mexFunction(int nlhs,mxArray *plhs[], int nrhs, const mxArray *prhs[])
lik.cpp文件
首次出现了Opencv的东西
功能:大概是把matlab图像转换为opencv能处理的图像,然后利用光流法跟踪,也有模板匹配。
//从matlab中加载图像到 image
void loadImageFromMatlab(const mxArray *mxImage, IplImage *image)
//欧几里得距离的计算
void euclideanDistance (CvPoint2D32f *point1, CvPoint2D32f *point2, float *match, int nPts)
//交叉相关:cross - correlation
void normCrossCorrelation
//lk.cpp的入口行数
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[]){}
lk.backup.cpp文件:
功能和lk.cpp差不多
void loadImageFromMatlab(const mxArray*mxImage, IplImage *image)
void mexFunction(int plhs_size, mxArray*plhs[], int prhs_size, const mxArray *prhs[])
其实下面两个文件并没有使用到哦。
ii.cpp文件:
得到积分图像
void mexFunction(intnlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])
ii2.cpp文件:
得到积分图像
void mexFunction(intnlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])