TLD取经之路(3)-- 始于足下--tldDemo.m tldInit.m

本文详细介绍了TLD目标跟踪算法的Matlab和C程序实现过程,从启动接口、初始化流程到核心模块运行原理,全面展示了如何使用这两种语言进行目标跟踪任务的开发。通过设置运行参数,可以实现在摄像头或文件中读取图像序列的跟踪功能,同时提供了更全面的DEMO程序以实现与官方视频中相同的效果。
摘要由CSDN通过智能技术生成

matlab版源程序:http://download.csdn.net/detail/cv_richie/4982673

C程序:http://download.csdn.net/detail/cv_richie/4982678

晚点我会把我注释的版本发上来。



程序运行从run_TLD.m或者run_TLD_demo.m开始,后者的功能更全,可以实现源代码作者主页上那些视频里的效果。

0. run_TLD_demo.m 
    程序启动的接口,这里可以设置DEMO程序的运行参数,结构体opt传递整个程序中的各种参量
.source 是图像的数据源,可以从摄像头读取图像('camera=1')和文件中读取图像序列('camera=0'),
.name 截图保存位置

  初始化了全局变量tld,包括opt中的参数以及tld跟踪监测的各种数据都靠他传递。

 ========================================================== 
1. tldDemo.m
  程序运行的主题,相当于C中的MAIN函数
  首先进行初始化
tldInitSource选择数据源
figure(2); set(2,'KeyPressFcn', @handleKey);  打开图像并初始化键盘输入的指针
tldInitFirstFrame 加载第一帧,加载初始框(就是检测目标框,选择摄像头用鼠标框定,选择文件读入则由文本文件中保存的信息载入)
tld = tldInit(opt,tld); %%关键!! % train initial detector 初始化detector 里面内容很多,另起介绍

===========================================================

2. tldInit.m

function tld = tldInit(opt,tld)

lk(0);

if ~isempty(tld);
    handle = tld.handle;
    tld = opt;
    tld.handle = handle;
else
    tld = opt;
end


% INITIALIZE DETECTOR =====================================================

% Scanning grid 创建扫描网格 tld.grid保存网格坐标 tld.scales保存网格尺度
[tld.grid tld.scales] = bb_scan(tld.source.bb,size(tld.source.im0.input),tld.model.min_win); %6*所有不同尺度下的网格数 1-4行为坐标 5尺度标号 6尺度下的网格列数标号

% Features 
tld.nGrid     = size(tld.grid,2);   %tld.nGrid保存网格数量
tld.features  = tldGenerateFeatures(tld.model.num_trees,tld.model.num_features,0);  %初始化FERN中的pixel comparison特征对tld.featrue.x为52*10 tld.feature.type='forest'

% Initialize Detector
fern(0); % cleanup 清除FERN分类器
fern(1,tld.source.im0.input,tld.grid,tld.features,tld.scales); % allocate structures 初始化ensemble分类器

% Temporal structures
tld.tmp.conf = zeros(1,tld.nGrid);
tld.tmp.patt = zeros(tld.model.num_trees,tld.nGrid);  %10*网格数

% RESULTS =================================================================

% Initialize Trajectory   初始化轨迹信息空间
tld.img             =   cell(1,length(tld.source.idx));  %CELL生成的是元胞
tld.snapshot     =   cell(1,length(tld.source.idx));
tld.dt                =   cell(1,length(tld.source.idx));
tld.bb               =   nan(4,length(tld.source.idx));  %nan生成的是空数组
tld.conf            =   nan(1,length(tld.source.idx));
tld.valid            =   nan(1,length(tld.source.idx));
tld.size              =   nan(1,length(tld.source.idx));
tld.trackerfailure = nan(1,length(tld.source.idx));
tld.draw    = zeros(2,0);
tld.pts     = zeros(2,0);
% Fill first fields
tld.img{1}  = tld.source.im0;
tld.bb(:,1) = tld.source.bb;
tld.conf(1) = 1;
tld.valid(1)= 1;
tld.size(1) = 1;

% TRAIN DETECTOR ==========================================================

% Initialize structures
tld.imgsize = size(tld.source.im0.input);  %tld.imgsize保存图像大小
tld.X       = cell(1,length(tld.source.idx)); % training data for fern 训练ensemble的样本
tld.Y       = cell(1,length(tld.source.idx)); 
tld.pEx     = cell(1,length(tld.source.idx)); % training data for NN 训练最近邻的样本
tld.nEx     = cell(1,length(tld.source.idx));
overlap     = bb_overlap(tld.source.bb,tld.grid); % bottleneck 返回与bb与每个网格的重叠比

% Target (display only)
tld.target = img_patch(tld.img{1}.input,tld.bb(:,1));%分割出目标区域的图像

% Generate Positive Examples产生正样本
[pX,pEx,bbP] = tldGeneratePositiveData(tld,overlap,tld.img{1},tld.p_par_init); %PX输出前十网格的特征,每行是一个网格,10列是一层随机;pex最大网格归一化图像 bbp最大网格的坐标
pY = ones(1,size(pX,2));%正样本的正标号
% disp(['# P patterns: ' num2str(size(pX,2))]);
% disp(['# P patches : ' num2str(size(pEx,2))]);

% Correct initial bbox
tld.bb(:,1) = bbP(1:4,:);%最大重叠度的网格 程序中把制定框转化为重叠度最大的网格

% Variance threshold
tld.var = var(pEx(:,1))/2; %方差分类器阈值为最大重叠度网格方差的的一半
% disp(['Variance : ' num2str(tld.var)]);

% Generate Negative Examples
[nX,nEx] = tldGenerateNegativeData(tld,overlap,tld.img{1});%重叠度小于0.2的网格中产生
% disp(['# N patterns: ' num2str(size(nX,2))]);
% disp(['# N patches : ' num2str(size(nEx,2))]);

% Split Negative Data to Training set and Validation set
[nX1,nX2,nEx1,nEx2] = tldSplitNegativeData(nX,nEx);%负样本随机平均分为两组
nY1  = zeros(1,size(nX1,2));%负样本的负标号

% Generate Apriori Negative Examples
%[anX,anEx] = tldGenerateAprioriData(tld);
%anY = zeros(1,size(anX,2));
% disp(['# apriori N patterns: ' num2str(size(anX,2))]);
% disp(['# apriori N patches : ' num2str(size(anEx,2))]);

tld.pEx{1}  = pEx; % save positive patches for later
tld.nEx{1}  = nEx; % save negative patches for later
tld.X{1}    = [pX nX1]; 
tld.Y{1}    = [pY nY1]; 
idx         = randperm(size(tld.X{1},2));
tld.X{1}    = tld.X{1}(:,idx);%随机化后的初始样本集
tld.Y{1}    = tld.Y{1}(:,idx);%随机化后的初始标号集

% Train using training set ------------------------------------------------

% Fern
bootstrap = 2;
fern(2,tld.X{1},tld.Y{1},tld.model.thr_fern,bootstrap);  %thr_fern为0.5训练初始随机厥分类器

% Nearest Neightbour 

tld.pex = [];
tld.nex = [];

tld = tldTrainNN(pEx,nEx1,tld);%训练初始NN分类器
tld.model.num_init = size(tld.pex,2);%训练后的正样本数

% Estimate thresholds on validation set  ----------------------------------

% Fern
conf_fern = fern(3,nX2);%输出为输入样本的分类结果即正样本可信度,可信度越高,分类效果不好,需要更新
tld.model.thr_fern = max(max(conf_fern)/tld.model.num_trees,tld.model.thr_fern);%该阈值影响后面的学习,越大则需要更新的样本越多

% Nearest neighbor
conf_nn = tldNN(nEx2,tld);
tld.model.thr_nn = max(tld.model.thr_nn,max(conf_nn));%该阈值越大,则需要被添加的模型正样本越多
tld.model.thr_nn_valid = max(tld.model.thr_nn_valid,tld.model.thr_nn);%跟踪时用到的有效性阈值



评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值