主要内容

跟踪一群飞鸟

这个例子展示了如何跟踪大量的对象。一大群鸟生成和全球最近邻多目标跟踪器,trackerGNN用于估计,每只鸟的运动在羊群。

场景定义

群运动模拟使用雷诺[1]提出的行为模型。在这个例子中,由1000个模拟鸟群,称为伯德的初始位置和速度以前保存。他们遵循植绒的三个规则:避碰,速度匹配,羊群定心。每个规则与体重和相关联的整体行为群中每个规则的相对权重。在这种情况下,选择权重导致羊群在某一点并创建一个密集的中心。其他重量设置可能会导致不同的行为出现。

跟踪这样的大型和密集群提出了两个挑战:

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

  2. 如何能够追踪个人与在这样一个密集的环境?

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

s =提高;%保持当前状态的随机数字生成器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] =移动(羊群,dt);allx (:,:, i) = x;plotTrack (tp1.Plotters (1), x)针对我国有关矿山截污库坝= findInView (x,绑定+ flockCenter,绑定+ flockCenter);plotTrack (tp2.Plotters (1) x(针对我国有关矿山截污库坝,:),truLabels(针对我国有关矿山截污库坝))drawnow结束

跟踪器的定义

定义跟踪器如例子所示如何有效地跟踪大量的对象

你观察到与遵循弯曲路径和选择一个常数模型定义的initctekf

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

此外,你选择更有效率Jonker-Volgenant分配算法,而不是默认的Munkres算法。

你想要跟踪快速确认和删除,并将确认和删除阈值设置为2[3]和[2 2],分别。

最后,你知道传感器扫描只有一小部分羊群在任何给定的扫描,所以你设置HasDetectableTrackIDsInput真正的能够通过检测跟踪器跟踪id。

以下行展示了跟踪器是如何配置上面的属性。你可以看到如何生成代码的追踪如何生成C代码跟踪和追踪这个例子是flockTracker_kernel.m保存在函数

%追踪= trackerGNN (“@initctekf FilterInitializationFcn”,“MaxNumTracks”, 1500年,…%”AssignmentThreshold”,[800],“任务”,“Jonker-Volgenant”,…%”ConfirmationThreshold”, [2 3],“DeletionThreshold”, 2 [2],……%”HasDetectableTrackIDsInput”,真正的);

跟踪羊群

接下来,您运行场景和跟踪羊群。

一个简化的模拟传感器模型使用detectFlock万博1manbetx支持功能。它模拟传感器扫描羊群从左到右,并捕获羊群跨度的五分之一在每个轴扫描。传感器有一个0.98的概率检测和噪声模拟使用正态分布的标准偏差0.1米关于每个位置的组件。

传感器报告其currentScan范围,用于提供检测跟踪器跟踪id。

清晰的flockTracker_kernelpositionSelector = [1 0 0 0 0 0 0;0 0 1 0 0 0 0;0 0 0 0 0 0 1);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)我= 1:numSteps t =我* dt;[检测,currentScan] = detectFlock (allx(:,:我),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显示了墨西哥人的追踪文件的性能。

总结

这个例子展示了如何跟踪大量的对象在现实的场景中,当扫描传感器仅报告在每个扫描物体的一小部分。这个例子展示了如何设置追踪大量的对象以及如何使用IDs检测跟踪输入防止轨道被删除。

引用

[1]克雷格·w·雷诺兹,羊群,牛群,和学校:“行为模式”,计算机图形学中,21卷,4号,1987年7月。

万博1manbetx支持功能

helperCreateDisplay

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

函数[tp1, tp2] = helperCreateDisplay (x,绑定)图(f =“可见”,“关闭”);集(f,“位置”[1 1 1425 700]);movegui (f,“中心”)h1 = uipanel (f,“字形大小”12“位置”,(。01 . 01相关性.98),“标题”,“群视图”);h2 = uipanel (f,“字形大小”12“位置”,(。51 . 01相关性.98),“标题”,“群中心”);flockCenter =意味着(x, 1);a1 =轴(h1,“位置”(0.05 - 0.05 0.9 - 0.9));网格(a1,“上”)tp1 = theaterPlot (“父”,a1);%羊群视图(截断)halfspan = 250;tp1。XLimits = 100 *轮([-halfspan + flockCenter (1) halfspan + flockCenter (1)] / 100);tp1。YLimits = 100 *轮([-halfspan + flockCenter (2) halfspan + flockCenter (2)] / 100);tp1。ZLimits = 100 *轮([-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 *轮([绑定+ flockCenter(1)绑定+ flockCenter (1)] / 10);tp2。YLimits = 10 *轮([绑定+ flockCenter(2)绑定+ flockCenter (2)] / 10);tp2。ZLimits = 10 *轮([绑定+ flockCenter(3)绑定+ flockCenter (3)] / 10);trackPlotter (tp2“DisplayName”,“真相”,“HistoryDepth”0,“标记”,“^”,“MarkerSize”6“ConnectHistory”,“关闭”,“字形大小”1);集(findall (a2,“类型”,“行”,“标签”,“tpTrackHistory_Truth”),“颜色”,“k”);%跟踪策划者TrackColor = 0.4470 - 0.7410 [0];%的蓝色TrackLength = 50;trackPlotter (tp1“DisplayName”,“跟踪”,“HistoryDepth”TrackLength,“ConnectHistory”,“关闭”,“标记”,“。”,“MarkerSize”3,“MarkerEdgeColor”TrackColor,“MarkerFaceColor”,TrackColor);集(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.Parent“类型”,“行”,“标签”,“tpTrackPositions_Tracks”),“线宽”2);集(findall (tp2.Parent“类型”,“行”,“标签”,“tpTrackHistory_Tracks”),“颜色”TrackColor,“线宽”1);视图(a2, 3)传说(“位置”,“东北”)组(f,“可见”,“上”)结束

detectFlock

函数模拟传感器模型。它返回一个数组的检测和电流传感器扫描限制。

函数[检测,scanLimits] = detectFlock (x, t)持续的σallDetections currentScan numScans numBoids =大小(x, 1);pd = 0.98;如果isempty(σ)σ= 0.1;oneDet = objectDetection (0 (0, 0, 0)“MeasurementNoise”σ,“ObjectAttributes”、结构);allDetections = repmat (oneDet numBoids 1);currentScan = 1;numScans = 5;结束%矢量化计算所有的检测x = x +σ* randn(大小(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) + spanPerScan * [(currentScan-1) currentScan];第1 =,(x (: 1) > = scanLimits (1) x (: 1) < = scanLimits (2));%添加Pd画=兰德(大小(第1));第1 =第1 &(画< pd);依据= allDetections(第1);检测= num2cell(依据);%促进扫描计数currentScan = currentScan + 1;如果currentScan > numScans currentScan = 1;结束结束

findInView

函数返回一个逻辑数组的位置,属于限制minBoundmaxBound

函数针对我国有关矿山截污库坝= findInView (x, minBound maxBound)针对我国有关矿山截污库坝= false(大小(x, 1), 1);针对我国有关矿山截污库坝(,)= (x (: 1) > minBound(1)和x (: 1) < maxBound & (1))(x (:, 2) > minBound(2)和x (:, 2) < maxBound & (2))(x (:, 3) > minBound(3)和x (:, 3) < maxBound (3));结束

helperVisualizeDisplay

函数显示了羊群和跟踪后跟踪。

函数helperVisualizeDisplay (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(:,:我))n =元素个数(allIDs{我});plotTrack (trap1 alltrax (1: n,:,我))边界= [tp2.XLimits; tp2.YLimits; tp2.ZLimits];针对我国有关矿山截污库坝= findInView (allx(:,:我),边界(:1),边界(:,2));plotTrack (trup2 allx(针对我国有关矿山截污库坝,:我),truLabels(针对我国有关矿山截污库坝))针对我国有关矿山截污库坝= findInView (alltrax (1: n,:,我),边界(:1),边界(:,2));plotTrack (trap2 alltrax(针对我国有关矿山截污库坝,:我),allIDs{我}(针对我国有关矿山截污库坝))drawnow结束