主要内容

追踪一群鸟

此示例显示如何跟踪大量对象。生成大群鸟类,并为全球最近的邻居多目标跟踪器,trackerGNN,用来估计鸟群中每只鸟的运动。

场景定义

采用Reynolds[1]提出的行为模型对鸟群运动进行了模拟。在这个例子中,鸟群由1000只被称为boids的模拟鸟组成,它们的初始位置和速度先前被保存。它们遵循三个聚集规则:避碰、速度匹配和聚集中心。每条规则都与一个权重相关,根据每条规则的相对权重,鸟群的整体行为就会显现出来。在这种情况下,选择重量,使羊群围绕某一点飞行,并创建一个密集的中心。其他的体重设置会导致不同的行为出现。

追踪如此庞大而密集的鸟群面临两个挑战:

  1. 如何有效地跟踪1000 boids?

  2. 如何在如此密集的环境中追踪个体boids ?

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

s =提高;%保持随机数生成器的当前状态rng (2019);%设置可重复结果的随机数生成器负载(“initialFlock.mat”“x”“v”);枫树= Helperflock(“NumBoids”、大小(x, 1),“collisticaviodance重量”,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] =移动(群,dt);allx(:,:,i)= x;plottrack(tp1.plotters(1),x)viniew = findinview(x,-bound + flockcenter,bound + flockcenter);plottrack(tp2.plotters(1),x(Inview,:),trulabels(Inview))绘制结束

跟踪器的定义

定义跟踪器,如示例所示如何高效地跟踪大量对象

你观察到boids沿着一条弯曲的路径,并选择由定义的常数转弯模型initctekf

要限制计算成本所需的时间,请降低粗糙成本计算阈值AssignmentThreshold到一个较低的值。

此外,您选择的效率更高Jonker-Volgenant作为赋值算法,而不是默认的MUNKRES.算法。

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

最后,您知道传感器在任何给定的扫描中仅扫描一小部分群,因此您设置了hasdetableTrackidsInput.真的才能将可检测的跟踪id传递给跟踪器。

下一行显示了如何使用上述属性配置跟踪器。中可以看到如何为跟踪器生成代码如何为跟踪器生成C代码,本例的跟踪器保存在函数flockTracker_kernel.m中

% tracker = 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_kernelpositionSelector = [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 (0, 3);边界=正(3 2);alltrax = 0(大小(allx));allIDs = repmat ({} 1 numSteps);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(tracks) trackid = 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] Craig W. Reynolds,“羊群、牛群和学校:行为模型”,《计算机图形学》,第21卷第4期,1987年7月。

金宝app支持功能

helperCreateDisplay

该函数创建示例显示并返回句柄到剧院图。

函数[tp1,tp2] = helperCreateDisplay(x,bound) f = figure(“可见”“离开”);集(f,“位置”,[1 1 1425 700]);MoveGui(F,“中心”)H1 = UIPanel(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 *圆形([ -  halfspan +普罗克中心(1)Halfspan + FlockCenter(1)] / 100);tp1.ylimits = 100 *圆形([ -  halfspan +植物(2)半尖+植物(2)] / 100);tp1.zlimits = 100 *圆形([ -  halfspan +植物(3)半尖+植物(3)] / 100);Trackplotter(TP1,“DisplayName”“真相”“HistoryDepth”0,“标记”“^”“MarkerSize”,4,“ConnectHistory”“离开”);set(findall(a1,“类型”“线”“标签”“tpTrackHistory_Truth”),“颜色”“k”);查看(A1,3)传奇('地点'“东北”%聚集中心A2 =轴(H2,'位置',[0.05 0.05 0.9 0.9]);网格(a2,“上”) tp2 =剧场情节(“父母”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);集(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);集(findall (tp1。父母,“类型”“线”“标签”“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);集(findall (tp2。父母,“类型”“线”“标签”“tpTrackHistory_Tracks”),“颜色”TrackColor,“行宽”1);视图(a2, 3)传说('地点'“东北”)组(f,“可见”“上”结束

detectFlock

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

函数[检测,scanLimits] = detectFlock (x, t)持续的Sigma alldetections潮流Numscans Numscans Numcans =尺寸(x,1);Pd = 0.98;如果Isempty (sigma) sigma = 0.1;oneDet = objectDetection (0 (0, 0, 0)“MeasurementNoise”σ,“ObjectAttributes”、结构);allDetections = repmat (oneDet numBoids 1);currentScan = 1;numScans = 5;结束所有检测的矢量化计算%x = x + sigma * randn(size(x));[alldetections.time] =交易(t);y = mat2cell(x',3,那些(1,尺寸(x,1)));[alldetections.measurent] =交易(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;如果currentScan > numScans currentScan = 1;结束结束

findInView

的范围内的位置返回逻辑数组minBoundmaxBound

函数Inview = findInview(x,minbound,maxbound)veniew = false(size(x,1),1);Inview(:) =(x(:,1)> minbound(1)&x(:,1)...(x(:,2)>minBound(2) & x(:,2)...(x(:,3)> minbound(3)&x(:,3)结束

helperVisualizeDisplay

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

函数helperVisualizeDisplay(tp1,tp2,truLabels,allx,allIDs,alltrax,i) trup1 = tp1. ploters (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)) bounds = [tp2.XLimits;tp2.YLimits;针对我国有关矿山截污库坝= findInView (allx(:,:我),边界(:1),边界(:,2));inView = findview (alltrax(1:n,:,i),bounds(:,1),bounds(:,2));plotTrack (trap2 alltrax(针对我国有关矿山截污库坝,:我),allIDs{我}(针对我国有关矿山截污库坝))drawnow结束