主要内容

追踪一群鸟

这个例子展示了如何跟踪大量的对象。基于全局最近邻多目标跟踪器,Trackergnn.,用于估计羊群中每只鸟的运动。

场景定义

使用Reynolds提出的行为模型模拟植绒运动[1]。在该示例中,羊群由1000个模拟鸟类组成,称为BoIDS,其初始位置和速度先前被保存。他们遵循三个植绒规则:碰撞避免,速度匹配和群居中。每个规则与重量相关联,群的整体行为从每个规则的相对加权出现。在这种情况下,选择重量,使得群围绕某个点飞行并产生密集的中心。其他权重设置会导致出现不同的行为。

跟踪如此大而密集的鸡群呈现两个挑战:

  1. 如何有效跟踪1000杆?

  2. 如何能够在如此密集的环境中跟踪个体笨拙?

下面的代码模拟了100步0.1秒的鸟群行为。左边的图显示了整个羊群,右边的图放大了羊群中心最密集的部分。

S = RNG;%保持随机数生成器的当前状态RNG(2019);%为可重复的结果设置随机数生成器负载(“initialflock.mat”“x”“v”);群= helperFlock (“NumBoids”、大小(x, 1),“CollisionAviodanceWeight”, 0.5,...“VelocityMatchingWeight”, 0.1,“FlockCenteringWeight”, 0.5,“速度”v,...“位置”, x,“BoidAcceleration”1);truLabels =字符串(num2str ((1: flock.NumBoids) '));绑定= 20;flockCenter =意味着(x, 1);[tp1, tp2] = helperCreateDisplay (x,绑定);%模拟了100个植绒步骤numSteps = 100;allx = repmat(x,[1 1 numSteps]);dt = 0.1;为了i = 1:numSteps [x,v] = move(flock,dt);allx (:,:, i) = x;plotTrack(tp1. ploters (1),x) inView = findview (x,-bound+flockCenter,bound+flockCenter);plotTrack (tp2.Plotters (1) x(针对我国有关矿山截污库坝,:),truLabels(针对我国有关矿山截污库坝))drawnow结尾

跟踪器的定义

如示例中所示,您定义了跟踪器如何有效跟踪大量对象

您观察到BOIDS遵循弯曲路径,然后选择由此定义的常量转弯模型initctekf.

为了限制计算成本所需的时间,可以降低中粗略的成本计算阈值分派察觉到一个较低的值。

此外,您选择更高效Jonker-Volgenant作为分配算法,而不是默认值Munkres算法。

您需要快速确认和删除曲目,将确认阈值和删除阈值分别设置为[2 3]和[2 2]。

最后,你知道传感器只能扫描鸟群的一小部分,所以你设置HasDetectableTrackIDsInput真正的才能将可检测的跟踪id传递给跟踪器。

以下行显示了如何使用上述属性配置跟踪器。您可以看到如何为racitioner生成代码如何为跟踪器生成C代码,并且此示例的跟踪器将保存在FlockTracker_kernel.M的函数中

%跟踪器= trackergnn(“filterinitializationfcn”,@ initctekf,“maxnumtracks”,1500,...%”AssignmentThreshold”,[800],“任务”,“Jonker-Volgenant”,…% " confirationthreshold ",[2 3],"DeletionThreshold",[2 2],…%”HasDetectableTrackIDsInput”,真正的);

跟踪羊群

接下来,您运行方案并跟踪群。

使用简化的传感器模型使用detectFlock金宝app支持功能。它模拟了一个从左到右扫描鸟群的传感器,并在每次扫描的x轴上捕捉到鸟群跨度的五分之一。该传感器有0.98的检测概率,噪声使用一个标准偏差0.1米左右的每个位置分量的正态分布模拟。

传感器报告其currentScan用于向跟踪器提供可检测的轨道ID的界限。

清晰的flocktracker_kernel.positionSelector = [1 0 0 0 0 0;0 0 1 0 0 0 0;0 0 0 0 1 0];trackIDs = 0 (0, 1,“uint32”);Trax =零(0,3);界限= INF(3,2);AllTrax = Zeros(尺寸(allx));ALLIDS = REPMAT({},1,NUMSTEP);trup2 = tp2.plotters(1);trap2 = tp2.plotters(2);trup2.historydepth = 2 * trap2.historydepth;Clearplotterdata(TP1)Clearplotterdata(TP2)为了i = 1:numSteps t = i*dt;[detections, currentScan] = detectFlock(allx(:,:,i),t);范围(:1)= currentScan;tracksInScan = findInView (trax,界限(:1),边界(:,2));(跟踪、信息)= flockTracker_kernel(检测t trackIDs (tracksInScan 1));trax = getTrackPositions(跟踪、positionSelector);如果〜isempty(曲目)trackids = uint32([tracks.trackid]');别的trackIDs = 0 (0, 1,“uint32”);结尾alltrax(1:尺寸(trax, 1), 1:3, i) = trax;allIDs{我}=字符串(trackIDs);helperVisualizeDisplay (tp1, tp2 truLabels、allx allIDs, alltrax,我)结尾rng(年代);将随机数生成器重置为以前的状态

在生成的代码中跟踪器的结果

下面的GIF在一个mex文件中显示了跟踪器的性能。

总结

这个示例展示了如何在一个真实的场景中跟踪大量的对象,其中扫描传感器在每次扫描中只报告一小部分对象。该示例演示了如何为大量对象设置跟踪器,以及如何使用可检测的轨迹id输入来防止轨迹被删除。

参考文献

[1]克雷格W. reynolds,“羊群,牛群和学校:行为模型”,计算机图形,卷。21,1987年7月4日。

金宝app支持功能

Helpercreatedisplay.

该函数创建示例显示,并返回两个戏剧情节的句柄。

功能[tp1,tp2] = helperCreateDisplay(x,bound) f = figure(“可见的”“关闭”);设置(f,“位置”,[1 1 1425 700]);movegui (f,“中央”h1 = upanel (f,“字体大小”12“位置”,[。01 .01 .48 .98],“标题”“群视图”);H2 = UIPanel(F,“字体大小”12“位置”,(。50.01 . 48.98],“标题”“群中心”);flockCenter =意味着(x, 1);a1 =轴(h1,“位置”,[0.05 0.05 0.9 0.9]);网格(a1,“上”) tp1 = theaterPlot(“父”, a1);%植绒视图(截断)halfspan = 250;tp1。XLimits = 100*round([-halfspan+flockCenter(1) halfspan+flockCenter(1)]/100);tp1。YLimits = 100*round([-halfspan+flockCenter(2) halfspan+flockCenter(2)]/100);tp1。ZLimits = 100*round([-halfspan+flockCenter(3) halfspan+flockCenter(3)]/100);trackPlotter (tp1“DisplayName”“真相”“HistoryDepth”,0,“标记”“^”“Markersize”4“connecthistory”“关闭”);集(findall (a1,“类型”“行”“标签”“tpTrackHistory_Truth”),“颜色”“k”);视图(a1, 3)传说(“位置”“东北”%聚集中心a2 =轴(h2,“位置”,[0.05 0.05 0.9 0.9]);网格(a2,“上”)tp2 = theaterplot(“父”a2);tp2。XLimits = 10*round([-bound+flockCenter(1) bound+flockCenter(1)]/10);tp2。YLimits = 10*round([-bound+flockCenter(2) bound+flockCenter(2)]/10);tp2。ZLimits = 10*round([-bound+flockCenter(3) bound+flockCenter(3)]/10);trackPlotter (tp2“DisplayName”“真相”“HistoryDepth”,0,...“标记”“^”“Markersize”6“connecthistory”“关闭”“字体大小”1);set(findall(a2,“类型”“行”“标签”“tpTrackHistory_Truth”),“颜色”“k”);%跟踪策划者trackcolor = [0 0.4470 0.7410];%的蓝色TrackLength = 50;trackPlotter (tp1“DisplayName”“轨道”“HistoryDepth”,trackLength,“connecthistory”“关闭”...“标记”“。”“Markersize”,3,“markeredgecolor”TrackColor,“MarkerFaceColor”, TrackColor);set(findall(tp1.parent,“类型”“行”“标签”“tptrackhistory_tracks”),...“颜色”TrackColor,“Markersize”,3,“markeredgecolor”, TrackColor);trackPlotter (tp2“DisplayName”“轨道”“HistoryDepth”,trackLength,“connecthistory”“在”...“标记”“s”“Markersize”8“markeredgecolor”TrackColor,“MarkerFaceColor”“没有任何”“字体大小”1);集(findall (tp2。父母,“类型”“行”“标签”“tpTrackPositions_Tracks”),“线宽”,2);set(findall(tp2.parent,“类型”“行”“标签”“tptrackhistory_tracks”),“颜色”TrackColor,“线宽”1);视图(a2, 3)传说(“位置”“东北”)设置(f,'可见的'“上”结尾

detectFlock

该函数模拟了传感器模型。它返回一个检测数组和当前传感器扫描限制。

功能[检测,Scanlimits] = DetectFlock(X,T)持续的sigma allDetections currentScan numScans numBoids = size(x,1);pd = 0.98;如果Isempty (sigma) sigma = 0.1;oneDet = objectDetection (0 (0, 0, 0)“MeasurementNoise”σ,“ObjectAttributes”,结构);alldetections = Repmat(Onedet,Numboids,1);潮流= 1;numscans = 5;结尾所有检测的百分比矢量化计算X = X + sigma*randn(size(X));[allDetections。时间)=交易(t);y = mat2cell (x ', 3,(1,尺寸(x, 1)));[allDetections。测量]=交易(y {:});%根据扫描次数限制覆盖区域flockXSpan = [min (x(: 1),[], 1)、马克斯(x (: 1), [], 1)];spanPerScan = (flockXSpan (2) -flockXSpan (1)) / numScans;scanLimits = flockXSpan(1) + spanscancan * [(currentScan-1) currentScan];第1 =,(x (: 1) > = scanLimits (1) x (: 1) < = scanLimits (2));%添加Pd画=兰德(大小(第1));= (draw%提升扫描计数Currentscan = Currentscan + 1;如果潮流> NumScans Currentscan = 1;结尾结尾

findInView

该函数返回一个逻辑阵列,用于落在限制范围内的位置minBoundmaxBound.

功能inView = findview (x,minBound,maxBound) inView = false(size(x,1),1);针对我国有关矿山截污库坝(,)= (x (: 1) > minBound(1)和x (: 1) < maxBound & (1))...(x(:,2)> minbound(2)&x(:,2)...(x (:, 3) > minBound(3)和x (:, 3) < maxBound (3));结尾

helperVisualizeDisplay

该功能显示跟踪后的羊群和轨迹。

功能HelperVisualizeSplay(TP1,TP2,Trulabels,ALLX,ALLIDS,ALLTRAX,I)TRUP1 = TP1.plotters(1);trap1 = tp1.plotters(2);trup2 = tp2.plotters(1);trap2 = tp2.plotters(2);plottrack(trup1,allx(:,:,i))n = numel(allids {i});plottrack(trap1,AllTrax(1:N,:i))绑定= [tp2.xlimits; tp2.ylimits; tp2.zlimits];Inview = findInview(allx(:,:,i),界限(:,1),界限(:,2));plottrack(trup2,allx(Inview,:,i),trulabels(Inview))Inview = findInview(AllTrax(1:N,:,I),界限(:,1),界限(:,2));Plottrack(trap2,AllTrax(Inview,:i),AllIds {i}(Inview))绘制结尾