主要内容

如何有效地跟踪对象的大数

这个例子说明了如何使用trackerGNN跟踪大量目标。类似的技术可以应用于trackerJPDA追踪者

介绍

在许多应用程序中,跟踪器需要跟踪数百或数千个对象。由于每个跟踪器的核心算法的计算复杂性,增加跟踪器维护的轨迹数量是一个挑战。特别是,跟踪器更新步骤中的两个常见阶段不容易伸缩:计算分配成本和执行分配。分配成本的计算是常见的trackerGNN,trackerJPDA, 和追踪者,并且在该示例中示出的技术可以使用任何这些跟踪器时被应用。每个跟踪器进行分配的方式是唯一的每个跟踪器,并可能需要定制的解决方案,以提高跟踪性能,这超出了这个例子的范围。金宝搏官方网站

场景

在本例中,您定义了一个包含900个平台的场景,以15×15的网格组织,每个网格单元包含4个平台。网格单元的目的是演示粗略成本计算的好处,稍后将在示例中解释。

以下代码在网格单元格中排列900对象并创建可视化。在左侧,显示了整个场景。在右侧,可视化在4个网格单元中放大。注意每个单元格都包含4个平台。

[platforms,tp,zoomedtp]=createPlatforms;

使用默认分配成本计算

这一节展示了使用trackerGNN用默认分配察觉.的分配察觉属性包含两个值:(C1, C2), 在哪里C1是用于分配和分配的阈值C2是在下一节中解释的粗计算的阈值。

当跟踪器被更新为一组新的检测时,它计算将每个检测分配到每个轨迹的代价。准确的成本计算必须考虑每个检测的测量和不确定度,以及每个轨道的预期测量和预期不确定度,如下所示。

默认情况下,C2设置为Inf,这需要计算所有轨道和检测组合的成本。这将导致更精确的赋值,但也需要更多的计算。您应该从默认设置开始,以确保跟踪器以最佳方式为跟踪分配检测,然后考虑降低值C2减少计算分配成本所需的时间。

在分配成本计算过程中,成本矩阵中值高于C1替换为Inf。这样做有助于赋值算法忽略不可能的赋值。

定义一个跟踪器,可以跟踪多达1000条轨迹。跟踪器采用默认的恒速扩展卡尔曼滤波器,其状态定义为[x;vx;y;vy;z;vz],这是用来通过positionSelector下面来获取位置组件。

跟踪器= trackergnn(“MaxNumTracks”,1000,“AssignmentThreshold”,[30 inf]);PositionSelector = [1 0 0 0 0 0;0 0 1 0 0 0;0 0 0 0 0 0];

在第一次调用步骤时,跟踪器实例化所有轨迹。要将实例化轨迹所需的时间与第一步所需的处理时间隔离开来,可以调用设置重启前步进跟踪。见支持功能金宝app运行跟踪器在这个例子中了解更多详情的结束。

[trkSummary,truSummary,info]=运行跟踪器(平台,跟踪器,位置选择器,tp,zoomedtp);
跟踪器设置时间:8.3108步骤1时间:3.7554步骤2时间:15.3029步骤3时间:14.1099步骤4时间:14.3506步骤5时间:14.3963

从现在开始的所有步骤都不会被发现。步骤6时间:0.53103步骤7时间:0.52582步骤8时间:0.50639步骤9时间:0.50909步骤10时间:0.16034方案完成。所有轨道现在都被删除了。

您可以通过检查轨迹分配度量值来分析跟踪结果。为了实现完美的跟踪,轨迹总数应等于平台数量,并且不应存在虚假、交换或发散轨迹。同样,真理摘要中不应存在遗漏的真理或中断。

AssignmentMetricsSummary(Trksummary,Trusummary)
轨道分配指标摘要:TotalNumTracks NumFalseTracks MaxSwapCount MaxDivergenceCount MaxDivergenceLength ______________ ______________ ____________ __________________ ___________________ 900 0 0 0 0真理分配指标摘要:TotalNumTruths NumMissingTruths MaxEstablishmentLength MaxBreakCount ______________ ________________ ______________________ _____________ 900 0 1 0

使用粗略分配成本计算

在上一节中,您看到跟踪器能够跟踪所有平台,但每个更新步骤都需要很长时间。大部分时间都在计算分配成本矩阵上。

检查成本矩阵,您可以看到它的绝大多数元素实际上是Inf。

cm = info.costmatrix;DISP(“成本矩阵有”+努梅尔(厘米)+“元素”。);DISP(“但有限值的数量是”+ numel(cm(Isfinite(cm)))+换行符)
成本矩阵有810000个元素。但有限值的数目是2700

以上结果表明,成本计算花费太多的时间在计算跟踪和检测的所有组合的分配成本。然而,大多数这些组合太远被分配,因为实际测量是基于传感器特性轨道预期测量太远。为了避免在计算所有费用的浪费,你可以使用粗成本计算。

进行粗略计算以验证哪些跟踪和检测组合可能需要精确的归一化距离计算。仅限粗略分配成本低于C2计算准确。粗略的成本计算如下图所示。探测用它的测量来表示z美元测量噪声$ r $.两个轨道被预测为所述检测的时间和投影到测量空间,由点示出美元z_ {e_1} $美元z_ {e_2} $.请注意,轨道不确定性未投影到测量空间,这使我们能够向量化粗略计算。这是一个粗略的估计,因为只考虑了检测周围的不确定性。在所描绘的示例中,第一轨道落在粗略计算门的外部,而第二轨道在其内部落入其中。因此,仅针对该检测和第二轨道的组合进行了准确的成本计算。

要使用粗的成本计算,释放跟踪器并修改其分配察觉为[30 200]。然后,重新运行跟踪器。

release(tracker)tracker.AssignmentThreshold=[30 200];[trkSummary,trsummary]=runTracker(平台,跟踪器,位置选择器,tp,zoomedtp);
跟踪器设置时间:6.5846步骤1时间:3.5863步骤2时间:3.4095步骤3时间:2.9347步骤4时间:2.8555步骤5时间:2.9397

从现在开始的所有步骤都不会被发现。步骤6时间:0.51446步骤7时间:0.52277步骤8时间:0.54865步骤9时间:0.50941步骤10时间:0.19085型方案完成。所有轨道现在都被删除了。

您可以看到步骤3-5现在需要的时间明显更少了。步骤2也比以前快,但仍然比步骤3-5慢。

要理解为什么步骤2比较慢,请考虑第一次跟踪器更新后的轨迹状态。状态包含位置信息,但速度仍然为零。跟踪器在计算分配代价时,将轨迹状态预测到检测次数,但由于轨迹速度为零,所以它们保持在相同的位置。这导致探测测量值与来自预测轨迹状态的预期测量值之间的距离很大。这些较大的分配成本使得分配算法更难找到最优分配,导致步骤2比步骤3-5花费更多的时间。

验证具有粗略成本计算的轨迹分配是否与不具有粗略成本计算的轨迹分配相同非常重要。如果轨迹分配度量不相同,则必须增加粗略计算门的大小。以下内容表明,跟踪仍然与上一节中的跟踪一样完美,但每个处理步骤所需的时间较少E

AssignmentMetricsSummary(Trksummary,Trusummary)
轨道分配指标摘要:TotalNumTracks NumFalseTracks MaxSwapCount MaxDivergenceCount MaxDivergenceLength ______________ ______________ ____________ __________________ ___________________ 900 0 0 0 0真理分配指标摘要:TotalNumTruths NumMissingTruths MaxEstablishmentLength MaxBreakCount ______________ ________________ ______________________ _____________ 900 0 1 0

使用外部成本计算

另一种控制计算成本分配所需的方法是通过使用自己的分配成本计算而不是默认的跟踪器使用。

外部成本计算可以考虑不属于轨道状态和预期测量的属性。它还可以使用不同的距离度量,例如欧几里德规范而不是归一化距离。选择要应用的成本计算的选择取决于问题的具体细节,测量空间,以及定义状态和测量的方式。

要使用外部成本计算,请释放跟踪器并设置其HasCostMatrixInput属性设置为true。每次更新时,您必须将自己的成本矩阵作为附加输入传递给跟踪器。参见支持函数金宝app运行跟踪器更多细节。

释放(跟踪器);tracker.hascostmatrixinput = true;[trcsummary,trusummary] = runtracker(平台,跟踪器,位置选择,TP,Zoomedtp);AssignmentMetricsSummary(Trksummary,Trusummary)
跟踪器设置时间:6.559步骤1时间:3.4394步骤2时间:1.7852步骤3时间:1.474步骤4时间:1.5312步骤5时间:1.5152

从现在开始的所有步骤都不会被发现。步骤6时间:0.60809步骤7时间:0.61374步骤8时间:0.616步骤9时间:0.63798步骤10时间:0.22762场景完成。所有轨道现在都被删除了。轨道分配指标摘要:TotalNumTracks NumFalseTracks MaxSwapCount MaxDivergenceCount MaxDivergenceLength ______________ ______________ ____________ __________________ ___________________ 900 0 0 0 0真理分配指标摘要:TotalNumTruths NumMissingTruths MaxEstablishmentLength MaxBreakCount ______________ ________________ ______________________ _____________ 900 0 1 0

如预期,使用外部成本计算功能时,处理时间甚至更低。

更改GNN分配算法

另一种尝试方法是使用不同的GNN分配算法,通过修改分配跟踪器的属性。

发布追踪(追踪)。赋值=“Jonker-Volgenant”;tracker.HasCostMatrixInput=true;runTracker(平台、跟踪器、位置选择器、tp、zoomedtp);
跟踪器设置时间:6.494第1步时间:3.5346第2步时间:1.894步骤3时间:3.1192第四步时间:3.1212第5步时间:3.1458

从现在开始的所有步骤都不会被发现。步骤6时间:0.61109步骤7时间:0.62456步骤8时间:0.61849步骤9时间:0.60604步骤10时间:0.22303的情况完成。所有轨道现在都被删除了。

Jonker-Volgenant算法执行第二步分配的速度比默认Munkres算法快。

Monte-Carlo模拟

如果你想在不修改跟踪器设置运行多个方案,也没有必要调用释放方法。相反,只要打电话给重启方法从跟踪器中清除以前的跟踪信息。这样,您就节省了实例化所有轨道所需的时间。注意下面的“跟踪器设置时间”相对于以前的运行。

复位(跟踪器)runTracker(平台,追踪器,positionSelector,TP,zoomedtp);
跟踪器设置时间:0.097531步骤1时间:3.4684步骤2时间:1.6592步骤3时间:3.1429步骤4时间:3.1274步骤5时间:3.0994

从现在开始的所有步骤都不会被发现。步骤6时间:0.63232步骤7时间:0.61857步骤8时间:0.61433步骤9时间:0.60698步骤10时间:0.25301场景完成。所有轨道现在都被删除了。

总结

这个例子说明如何跟踪大量的对象。当跟踪多个对象,跟踪器花费在计算用于跟踪和检测的每个组合的成本分配的处理时间的很大一部分。你看到了如何使用成本计算门槛提高花在计算分配成本的时间。此外,该示例演示了如何使用外部成本计算,其可设计为你有特别的跟踪问题计算效率更高。

您可以降低成本分配阈值或使用外部成本计算来提高成本分配的速度trackerJPDA追踪者

金宝app支持功能

创建平台

这个函数创建一个20x20的网格,每个网格单元的2x2平台的平台。

功能(平台、tp zoomedtp) = createPlatforms%这是运行跟踪器并显示结果的辅助功能。它%可能在将来被移除。nh=15;水平网格细胞的%数nv = 15;%垂直网格单元的数量nsq = 2;网格单元格中的% 2x2平台nPl=nh*nv*nsq^2;%平台数量XGV = sort(-50 + repmat(100 * (1:nh), [1 nsq]));Ygv = sort(-50 + repmat(100 * (1:nv), [1 nsq])));(X, Y) = meshgrid (xgv ygv);《不扩散核武器条约》= nsq / 2;Xshift = 10*(((-npts+1):npts) -5;yshift = xshift;Xadd = repmat(xshift, [1 nh]);Yadd = repmat(yshift, [1 nv]); / /显示当前位置[Xx, Yy] = meshgrid(xadd,yadd);X = X + Xx; Y = Y + Yy; pos = [X(:),Y(:),zeros(numel(X),1)];%以下创建结构为平台,这是一个数组%稍后用于轨迹分配度量。VEL = [3 1 0];%平台速度平台= Repmat(Struct(“平台形”, 1“位置”,[0 0 0],“速度”韦尔),不良贷款,1);对于i = 1:npl平台(i).platformid = i;平台(i).Position(:) = POS(我,:);终止%的可视化f=数字(“位置”,[1 1 1425 700]);MoveGui.中央;H1 = UIPanel(F,'字体大小'12“位置”[01 0.01 0.48 0.98],“标题”,“场景视图”);a1 =轴(h1,“位置”,[0.05 0.05 0.9 0.9]);tp = theaterPlot ('父母'a1,'xlimits',[0 NH * 100],“YLimits”,[0 NV * 100]);组(A1,'xtick',0:100:NH * 100)组(A1,“YTick”,0:100:NV * 100)网格页= trackPlotter (tp,'标签','真相','标记',“^”,'MarkerEdgeColor',数k,“MarkerSize”4,“HistoryDepth”,10); plotTrack(pp,重塑([platforms.Position],3,[]));轨迹绘图仪(tp,'标签',“轨道”,'MarkerEdgeColor',“b”,“MarkerSize”6“HistoryDepth”10);c = (a1。父母,“儿童”);对于i=1:numel(c)如果isa (c(我),“matlab.graphics.illustration.Legend”)组(c(我),'可见的','离开')终止终止H2 = UIPanel(F,'字体大小'12“位置”,[.51 .01 .48 .98],“标题”,“放大视图”);a2 =轴(h2,“位置”,[0.05 0.05 0.9 0.9]); zoomedtp=剧场图('父母'a2'xlimits'(400 500),“YLimits”,[400 500]);套(A2,'xtick',400:100:500)套(a2,“YTick”,400:100:500)格zoomedpp = trackPlotter(zoomedtp,“DisplayName的”,'真相','标记',“^”,'MarkerEdgeColor',数k,“MarkerSize”6“HistoryDepth”10);plottrack(zoomedpp,重塑([platforms.position],3,[])');Trackplotter(Zoomedtp,“DisplayName的”,“轨道”,'MarkerEdgeColor',“b”,“MarkerSize”8.“HistoryDepth”10“连接历史”,“开”,'字体大小',1);终止

运行跟踪器

此函数用于运行跟踪器、更新绘图仪并收集轨迹分配指标。

功能[trkSummary,truSummary,info]=运行跟踪器(平台,跟踪器,位置选择器,tp,zoomedtp)%这是运行跟踪器并显示结果的辅助功能。它%可能在将来被移除。页= findPlotter (tp,'标签','真相');TRP = findPlotter(TP,'标签',“轨道”);zoomedpp = findPlotter (zoomedtp,“DisplayName的”,'真相');zoomedtrp = findplotter(zoomedtp,“DisplayName的”,“轨道”);%为了节省时间,预先分配所有检测并动态分配它们。npl = numel(平台);det = ObjectDetection(0,[0; 0; 0]);DETS = REPMAT({det},[npl,1]);定义一个轨道分配指标对象。Tam = trackassignmentmetrics;%带来的可视化回来。set(tp.parent.parent.parent,'可见的',“开”)hasExternalCostFunction = tracker.HasCostMatrixInput;%测量需要设置跟踪了时间。抽搐如果~ isLocked(跟踪)如果HaseXternalCostFunction设置(跟踪器,DET,0,0);别的设置(追踪,侦破,0);终止终止复位(跟踪器)DISP(“跟踪器设置时间:”+ TOC);%运行5个步骤,对所有平台进行检测。对于t=1:5对于i = 1:npl det {i} .time = t;DETS {i} .measurement =平台(i).position(:);终止抽搐如果hasExternalCostFunction如果isLocked(跟踪)%用途predictTracksToTime让所有的预测轨迹。allTracks = predictTracksToTime(追踪,'全部',t);别的allTracks = [];终止costMatrix = predictedEuclidean(allTracks,dets的,positionSelector);[轨道,〜,〜,信息] =跟踪器(dets的,吨,costMatrix);别的[痕迹,~,~,信息]=追踪(侦破,t);终止trPos = getTrackPositions(轨道,位置选择器);trIDs =字符串([tracks.TrackID]”);DISP(“步骤”+t+“ 时间: ”+ toc)%更新的情节。plottrack(pp,重塑([platforms.position],3,[])');Plottrack(TRP,TRPO);plottrack(zoomedpp,重塑([platforms.position],3,[])');Plottrack(zoomedtrp,trpos,trids);drawn%更新轨迹分配度量对象。如果nargout [trkSummary,truSummary] = TAM(轨道,平台);终止%更新平台位置。对于i = 1:npl平台(i).position = platforms(i).position +平台(i)。velocity;终止终止snapnow%运行步骤,没有检测到跟踪器删除所有曲目。DISP(“从现在开始的所有步骤都不会被发现。”)尽管~isempty(tracks) t = t+1;抽搐如果hasExternalCostFunction allTracks = predictTracksToTime(跟踪器,'全部',t);costMatrix = predictedEuclidean(allTracks,{},positionSelector);曲目=跟踪器({},T,costMatrix);别的轨迹=跟踪器({},t);终止DISP(“步骤”+t+“ 时间: ”+ toc)%更新曲目情节的位置。trPos=getTrackPositions(轨道、位置选择器);trIDs=string([tracks.TrackID]');%更新的情节。plottrack(pp,重塑([platforms.position],3,[])');Plottrack(TRP,TRPO);plottrack(zoomedpp,重塑([platforms.position],3,[])');Plottrack(zoomedtrp,trpos,trids);drawn%更新平台位置。对于i = 1:npl平台(i).position = platforms(i).position +平台(i)。velocity;终止终止DISP(”场景。所有的音轨现在都被删除了。”+ newline) clearData(pp) clearData(trp) clearData(zoomedpp) clearData(zoomedtrp) set(tp.Parent.Parent.Parent,'可见的','离开')%防止过度快照drawn终止

predictedEuclidean

的函数计算从检测测量位置和从轨道预测位置之间的欧几里得距离。

功能euclidDist = predictedEuclidean(跟踪、检测、positionSelector)%这是运行跟踪器并显示结果的辅助功能。它%可能在将来被移除。如果isempty(轨道)||缺乏(检测)eucliddist =零(磁轨(轨道),磁数(检测));返回终止predgegentstates = [tracks.state];predatePositions = PositionSelector *预测状态;dets = [检测{:}];测量值= [dets.measurement];eucliddist =零(磁轨(轨道),磁数(检测));对于i = 1:numel(检测)diffs = bsxfun(@minus, predictedPositions',measuredPositions(:,i)');euclidDist(:,i) =√(sum((diff .* diff),2));终止终止

assignmentMetricsSummary

的功能显示在一个表中的形式键分配指标。

功能trkSummary = rmfield(trkSummary, {)“TotalSwapCount”,'TotalDivergenceCount',...“TotalDivergenceLength”,“MaxRedundancyCount”,“总冗余计数”,...'maxredundancyLength','累加性的假时期'});truSummary = rmfield(truSummary, {“TotalEstablishmentLength”,“TotalBreakCount”,...'maxbreaklength','totalebreaklength'});trkTable = struct2table(trkSummary);truTable = struct2table(truSummary);DISP(“跟踪分配指标总结:”) disp trkTable disp (“真理分配指标总结:”) disp (truTable)终止