Как эффективно отследить большие количества объектов

Этот пример показывает, как использовать trackerGNN, чтобы отследить большие количества целей. Подобные методы могут быть применены к trackerJPDA и trackerTOMHT также.

Введение

Во многих приложениях средства отслеживания требуются, чтобы отслеживать сотни или тысячи объектов. Увеличение числа дорожек, сохраняемых средством отслеживания, является проблемой, вызванной вычислительной сложностью алгоритма в ядре каждого средства отслеживания. В частности, два общих этапа на шаге обновления средства отслеживания не легко масштабируемы: вычисление стоимости присвоения и выполнение присвоения. Расчет стоимости присвоения характерен для trackerGNN, trackerJPDA и trackerTOMHT, и методы, показанные в этом примере, могут быть применены при использовании любого из этих средств отслеживания. Путем каждое средство отслеживания выполняет присвоение, уникально для каждого средства отслеживания и может потребовать, чтобы специализированные решения улучшали производительность средства отслеживания, которые выходят за рамки этого примера.

Сценарий

В целях этого примера вы задаете сценарий, который содержит 900 платформ, организованных в 15 15 сетка, с каждой ячейкой сетки, содержащей 4 платформы. Цель ячеек сетки состоит в том, чтобы продемонстрировать преимущество крупного расчета стоимости, объясненного позже в примере.

Следующий код располагает 900 объектов в ячейке сетки и создает визуализацию. Слева, целый сценарий показывают. Справа, визуализация увеличивает масштаб 4 ячеек сетки. Обратите внимание, что каждая ячейка содержит 4 платформы.

[platforms,tp,zoomedtp] = createPlatforms;

Используйте расчет стоимости присвоения по умолчанию

Этот раздел показывает результаты отслеживания платформ, заданных выше использования trackerGNN с AssignmentThreshold по умолчанию. Свойство AssignmentThreshold содержит два значения: [C1 C2], где C1 является порогом, используемым для присвоения и C2, является порогом для крупного вычисления, объясненного в следующем разделе.

Когда средство отслеживания обновляется с новым набором обнаружений, оно вычисляет стоимость присвоения каждого обнаружения к каждой дорожке. Точный расчет стоимости должен учесть измерение и неуверенность в каждом обнаружении, а также ожидаемое измерение и ожидаемую неуверенность от каждой дорожки, как изображено ниже.

По умолчанию C2 установлен в Inf, который требует, чтобы затраты на все комбинации дорожки и обнаружения были вычислены. Это приводит к более точному присвоению, но более в вычислительном отношении интенсивно. Необходимо начать с настройки по умолчанию убеждаться, что средство отслеживания присваивает обнаружения дорожкам лучшим способом, и затем полагайте, что понижение значения C2 уменьшает время, требуемое для вычисления стоимости присвоения.

Во время расчета стоимости присвоения элементы матрицы стоимости, значения которой выше, чем C1, заменяются Inf. Выполнение так помогает алгоритму присвоения проигнорировать невозможные присвоения.

Задайте средство отслеживания, которое может отследить до 1 000 дорожек. Средство отслеживания использует расширенный Фильтр Калмана постоянной скорости по умолчанию, и его состояние задано как [x;vx;y;vy;z;vz], который используется positionSelector ниже, чтобы получить компоненты положения.

tracker = 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];

На первом вызове шага средство отслеживания инстанцирует всех дорожек. Изолировать время, требуемое инстанцировать дорожек со времени вычислений, потребовало для первого шага, можно вызвать setup и reset прежде, чем продвинуться средство отслеживания. Смотрите функцию поддержки runTracker в конце этого примера для получения дополнительной информации.

[trkSummary,truSummary,info] = runTracker(platforms,tracker,positionSelector,tp,zoomedtp);
Tracker set up time: 6.2629
Step 1 time: 3.0754
Step 2 time: 13.5342
Step 3 time: 12.2972
Step 4 time: 12.3253
Step 5 time: 12.5448

All steps from now are without detections.
Step 6 time: 0.48672
Step 7 time: 0.46594
Step 8 time: 0.50402
Step 9 time: 0.49171
Step 10 time: 0.13955
Scenario done. All tracks are now deleted.

Вы анализируете результаты отслеживания путем исследования метрических значений присвоения дорожки. Для совершенного отслеживания общего количества дорожек должно быть равно количеству платформ и не должно быть никакой лжи, подкачанных, или расходящихся дорожек. Точно так же не должно быть никакой недостающей истины или не прерывает сводные данные истины.

assignmentMetricsSummary(trkSummary,truSummary)
Track assignment metrics summary:
    TotalNumTracks    NumFalseTracks    MaxSwapCount    MaxDivergenceCount    MaxDivergenceLength
    ______________    ______________    ____________    __________________    ___________________

         900                0                0                  0                      0         

Truth assignment metrics summary:
    TotalNumTruths    NumMissingTruths    MaxEstablishmentLength    MaxBreakCount
    ______________    ________________    ______________________    _____________

         900                 0                      1                     0      

Используйте крупный расчет стоимости присвоения

В предыдущем разделе вы видели, что средство отслеживания может отследить все платформы, но каждый шаг обновления занимает много времени. Наиболее часто был потрачен на вычисление матрицы стоимости присвоения.

Исследуя матрицу стоимости, вы видите, что подавляющим большинством ее элементов является, на самом деле, Inf.

cm = info.CostMatrix;
disp("Cost matrix has " + numel(cm) + " elements.");
disp("But the number of finite values is " + numel(cm(isfinite(cm))) + newline)
Cost matrix has 810000 elements.
But the number of finite values is 2700

Вышеупомянутый результат показывает, что расчет стоимости проводит слишком много времени при вычислении стоимости присвоения всех комбинаций дорожки и обнаружения. Однако большинство этих комбинаций слишком далеко, чтобы быть присвоенным, как фактическое измерение слишком далеко от ожидаемого измерения дорожки на основе характеристик датчика. Чтобы избежать отходов в вычислении всех затрат, можно использовать крупный расчет стоимости.

Крупное вычисление сделано, чтобы проверить, какие комбинации дорожки и обнаружения могут потребовать точного нормированного расчета расстояния. Только комбинации, крупная стоимость присвоения которых ниже, чем C2, вычисляются точно. Крупный расчет стоимости изображен в изображении ниже. Обнаружение представлено его шумом измерения и измерения. Две дорожки предсказаны ко времени обнаружения и спроектированы к пробелу измерения, изображенному точками и. Обратите внимание на то, что неуверенность дорожки не спроектирована к пробелу измерения, который позволяет нам векторизовать крупное вычисление. Это - грубая оценка, потому что только неуверенность по поводу обнаружения учтена. В изображенном примере первая дорожка падает за пределами крупного логического элемента вычисления, в то время как вторая дорожка падает в нем. Таким образом точный расчет стоимости только сделан для комбинации этого обнаружения и второй дорожки.

Чтобы использовать крупный расчет стоимости, выпустите средство отслеживания и измените его AssignmentThreshold к значению [30 200]. Затем повторно выполните средство отслеживания.

release(tracker)
tracker.AssignmentThreshold = [30 200];
[trkSummary,truSummary] = runTracker(platforms,tracker,positionSelector,tp,zoomedtp);
Tracker set up time: 5.4344
Step 1 time: 2.8964
Step 2 time: 3.1965
Step 3 time: 2.8143
Step 4 time: 2.7336
Step 5 time: 2.602

All steps from now are without detections.
Step 6 time: 0.47158
Step 7 time: 0.4913
Step 8 time: 0.46417
Step 9 time: 0.45706
Step 10 time: 0.12533
Scenario done. All tracks are now deleted.

Вы замечаете, что шаги 3-5 теперь требуют, чтобы значительно меньше времени завершилось. Шаг 2 также быстрее, чем он раньше был, но еще медленнее, чем шаги 3-5.

Чтобы понять, почему шаг 2 медленнее, рассмотрите состояния дорожки после первого обновления средства отслеживания. Состояния содержат информацию о положении, но скорость является все еще нулевой. Когда средство отслеживания вычисляет стоимость присвоения, оно предсказывает, что дорожка утверждает ко временам обнаружения, но поскольку дорожки имеют нулевую скорость, они остаются в том же положении. Это приводит к большим расстояниям между измерениями обнаружения и ожидаемыми измерениями от предсказанных состояний дорожки. Эти относительно большие затраты присвоения делают его тяжелее для алгоритма присвоения, чтобы найти лучшее присвоение, которое заставляет шаг 2 занимать больше времени, чем шаги 3-5.

Важно проверить, что присвоение дорожки с крупным расчетом стоимости остается то же самое как без него. Если метрики присвоения дорожки не являются тем же самым, необходимо увеличить размер крупного логического элемента вычисления. Следующее показывает, что отслеживание все еще совершенно, как это было в предыдущем разделе, но каждый шаг обработки занял меньше времени.

assignmentMetricsSummary(trkSummary,truSummary)
Track assignment metrics summary:
    TotalNumTracks    NumFalseTracks    MaxSwapCount    MaxDivergenceCount    MaxDivergenceLength
    ______________    ______________    ____________    __________________    ___________________

         900                0                0                  0                      0         

Truth assignment metrics summary:
    TotalNumTruths    NumMissingTruths    MaxEstablishmentLength    MaxBreakCount
    ______________    ________________    ______________________    _____________

         900                 0                      1                     0      

Используйте вычисление внешней стоимости

Другим способом управлять временем, которое требуется, чтобы вычислить присвоение стоимости, является при помощи вашего собственного расчета стоимости присвоения вместо значения по умолчанию использование средства отслеживания.

Вычисление внешней стоимости может учесть атрибуты, которые не являются частью состояния дорожки и ожидаемого измерения. Это может также использовать различные метрики расстояния, например, Евклидова норма вместо нормированного расстояния. Выбор которого расчет стоимости применяться зависит от специфических особенностей проблемы, пробела измерения, и как вы задаете состояние и измерение.

Чтобы использовать вычисление внешней стоимости, вы выпускаете средство отслеживания и устанавливаете его свойство HasCostMatrixInput на истину. Необходимо передать собственную матрицу стоимости как дополнительный вход с каждым обновлением средства отслеживания. Дополнительную информацию см. в функции поддержки runTracker.

release(tracker);
tracker.HasCostMatrixInput = true;
[trkSummary,truSummary] = runTracker(platforms,tracker,positionSelector,tp,zoomedtp);
assignmentMetricsSummary(trkSummary,truSummary)
Tracker set up time: 5.4425
Step 1 time: 2.7897
Step 2 time: 1.5586
Step 3 time: 1.365
Step 4 time: 1.4195
Step 5 time: 1.3637

All steps from now are without detections.
Step 6 time: 0.55515
Step 7 time: 0.55081
Step 8 time: 0.5411
Step 9 time: 0.5556
Step 10 time: 0.19762
Scenario done. All tracks are now deleted.

Track assignment metrics summary:
    TotalNumTracks    NumFalseTracks    MaxSwapCount    MaxDivergenceCount    MaxDivergenceLength
    ______________    ______________    ____________    __________________    ___________________

         900                0                0                  0                      0         

Truth assignment metrics summary:
    TotalNumTruths    NumMissingTruths    MaxEstablishmentLength    MaxBreakCount
    ______________    ________________    ______________________    _____________

         900                 0                      1                     0      

Как ожидалось время вычислений еще ниже при использовании функции вычисления внешней стоимости.

Измените алгоритм присвоения GNN

Другая опция, чтобы попробовать использует различный алгоритм присвоения GNN, который может быть более эффективным в нахождении присвоения путем изменения свойства Assignment средства отслеживания.

release(tracker)
tracker.Assignment = 'Jonker-Volgenant';
tracker.HasCostMatrixInput = true;
runTracker(platforms,tracker,positionSelector,tp,zoomedtp);
Tracker set up time: 5.4339
Step 1 time: 2.9202
Step 2 time: 1.7385
Step 3 time: 2.9389
Step 4 time: 2.9151
Step 5 time: 2.8985

All steps from now are without detections.
Step 6 time: 0.54947
Step 7 time: 0.54664
Step 8 time: 0.53913
Step 9 time: 0.60383
Step 10 time: 0.20843
Scenario done. All tracks are now deleted.

Алгоритм Jonker-Volgenant выполняет присвоение на втором шаге быстрее относительно алгоритма Munkres по умолчанию.

Симуляция Монте-Карло

Если вы хотите запустить несколько сценариев, не изменяя настройки средства отслеживания, нет никакой потребности вызвать метод release. Вместо этого только вызовите метод reset, чтобы очистить предыдущую информацию о дорожке от средства отслеживания. Таким образом, вы экономите время, требуемое инстанцировать всех дорожек. Обратите внимание, что "Средство отслеживания настроило время" ниже относительно предыдущих выполнений.

reset(tracker)
runTracker(platforms,tracker,positionSelector,tp,zoomedtp);
Tracker set up time: 0.084152
Step 1 time: 2.7899
Step 2 time: 1.5324
Step 3 time: 2.9437
Step 4 time: 2.9087
Step 5 time: 2.9117

All steps from now are without detections.
Step 6 time: 0.54433
Step 7 time: 0.54118
Step 8 time: 0.54495
Step 9 time: 0.5426
Step 10 time: 0.19652
Scenario done. All tracks are now deleted.

Сводные данные

Этот пример показал, как отследить большие количества объектов. При отслеживании многих объектов средство отслеживания тратит большую часть времени вычислений на вычислении присвоения стоимости для каждой комбинации дорожки и обнаружения. Вы видели, как использовать порог расчета стоимости, чтобы улучшить время, проведенное относительно вычисления стоимости присвоения. Кроме того, пример показал, как использовать вычисление внешней стоимости, которое может быть разработано, чтобы быть более в вычислительном отношении эффективным для конкретной проблемы отслеживания, которую вы имеете.

Можно уменьшать порог присвоения стоимости или использовать вычисление внешней стоимости, чтобы улучшить скорость trackerJPDA и trackerTOMHT также.

Поддерживание функций

createPlatforms

Эта функция создает платформы в 20x20 сетка с 2x2 платформы на ячейку сетки.

function [platforms,tp,zoomedtp] = createPlatforms
% This is a helper function to run the tracker and display the results. It
% may be removed in the future.
nh  = 15; % Number of horizontal grid cells
nv  = 15; % Number of vertical grid cells
nsq = 2;  % 2x2 platforms in a grid cell
nPl = nh*nv*nsq^2; % Overall number of platforms
xgv = sort(-50 + repmat(100 * (1:nh), [1 nsq]));
ygv = sort(-50 + repmat(100 * (1:nv), [1 nsq]));
[X,Y] = meshgrid(xgv,ygv);

npts = 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)];

% The following creates an array of struct for the platforms, which are
% used later for track assignment metrics.
vel = [3 1 0]; % Platform velocity
platforms = repmat(struct('PlatformID', 1, 'Position', [0 0 0], 'Velocity', vel),nPl,1);
for i = 1:nPl
    platforms(i).PlatformID  = i;
    platforms(i).Position(:) = pos(i,:);
end

% Visualization
f = figure('Position',[1 1 1425 700]);
movegui center;
h1 = uipanel(f,'FontSize',12,'Position',[.01 .01 .48 .98],"Title","Scene View");
a1 = axes(h1,'Position',[0.05 0.05 0.9 0.9]);
tp = theaterPlot('Parent', a1, 'XLimits',[0 nh*100], 'YLimits',[0 nv*100]);
set(a1,'XTick',0:100:nh*100)
set(a1,'YTick',0:100:nv*100)
grid on
pp = trackPlotter(tp,'Tag','Truth','Marker','^','MarkerEdgeColor','k','MarkerSize',4,'HistoryDepth',10);
plotTrack(pp,reshape([platforms.Position],3,[])');
trackPlotter(tp, 'Tag','Tracks','MarkerEdgeColor','b','MarkerSize',6,'HistoryDepth',10);
c = get(a1.Parent,'Children');
for i = 1:numel(c)
    if isa(c(i),'matlab.graphics.illustration.Legend')
        set(c(i),'Visible','off')
    end
end

h2 = uipanel(f,'FontSize',12,'Position',[.51 .01 .48 .98],'Title','Zoomed View');
a2 = axes(h2,'Position',[0.05 0.05 0.9 0.9]);
zoomedtp = theaterPlot('Parent', a2, 'XLimits',[400 500], 'YLimits',[400 500]);
set(a2,'XTick',400:100:500)
set(a2,'YTick',400:100:500)
grid on
zoomedpp = trackPlotter(zoomedtp,'DisplayName','Truth','Marker','^','MarkerEdgeColor','k','MarkerSize',6,'HistoryDepth',10);
plotTrack(zoomedpp,reshape([platforms.Position],3,[])');
trackPlotter(zoomedtp, 'DisplayName','Tracks','MarkerEdgeColor','b','MarkerSize',8,'HistoryDepth',10,'ConnectHistory','on','FontSize',1);
end

runTracker

Эта функция запускает средство отслеживания, обновляет плоттеры и собирает метрики присвоения дорожки.

function [trkSummary,truSummary,info] = runTracker(platforms,tracker,positionSelector,tp,zoomedtp)
% This is a helper function to run the tracker and display the results. It
% may be removed in the future.

pp = findPlotter(tp,'Tag','Truth');
trp = findPlotter(tp, 'Tag','Tracks');
zoomedpp = findPlotter(zoomedtp,'DisplayName','Truth');
zoomedtrp = findPlotter(zoomedtp, 'DisplayName','Tracks');

% To save time, pre-allocate all the detections and assign them on the fly.
nPl = numel(platforms);
det = objectDetection(0,[0;0;0]);
dets = repmat({det},[nPl,1]);

% Define a track assignment metrics object.
tam = trackAssignmentMetrics;

% Bring the visualization back.
set(tp.Parent.Parent.Parent,'Visible','on')

hasExternalCostFunction = tracker.HasCostMatrixInput;

% Measure the time it takes to set the tracker up.
tic
if ~isLocked(tracker)
    if hasExternalCostFunction
        setup(tracker,dets,0,0);
    else
        setup(tracker,dets,0);
    end
end
reset(tracker)
disp("Tracker set up time: " + toc);

% Run 5 steps with detections for all the platforms.
for t = 1:5
    for i = 1:nPl
        dets{i}.Time = t;
        dets{i}.Measurement = platforms(i).Position(:);
    end

    tic
    if hasExternalCostFunction
        if isLocked(tracker)
            % Use predictTracksToTime to get all the predicted tracks.
            allTracks = predictTracksToTime(tracker,'all',t);
        else
            allTracks = [];
        end
        costMatrix = predictedEuclidean(allTracks,dets,positionSelector);
        [tracks,~,~,info] = tracker(dets,t,costMatrix);
    else
        [tracks,~,~,info] = tracker(dets,t);
    end
    trPos = getTrackPositions(tracks, positionSelector);
    trIDs = string([tracks.TrackID]');
    disp("Step " + t + " time: " + toc)

    % Update the plot.
    plotTrack(pp,reshape([platforms.Position],3,[])');
    plotTrack(trp,trPos);
    plotTrack(zoomedpp,reshape([platforms.Position],3,[])');
    plotTrack(zoomedtrp,trPos,trIDs);
    drawnow

    % Update the track assignment metrics object.
    if nargout
        [trkSummary, truSummary] = tam(tracks,platforms);
    end

    % Update the platform positions.
    for i = 1:nPl
        platforms(i).Position = platforms(i).Position + platforms(i).Velocity;
    end
end
snapnow

% Run steps with no detections until the tracker deletes all the tracks.
disp("All steps from now are without detections.")
while ~isempty(tracks)
    t = t+1;
    tic
    if hasExternalCostFunction
        allTracks = predictTracksToTime(tracker,'all',t);
        costMatrix = predictedEuclidean(allTracks,{},positionSelector);
        tracks = tracker({},t,costMatrix);
    else
        tracks = tracker({},t);
    end
    disp("Step " + t + " time: " + toc)

    % Update the position of the tracks to plot.
    trPos = getTrackPositions(tracks,positionSelector);
    trIDs = string([tracks.TrackID]');

    % Update the plot.
    plotTrack(pp,reshape([platforms.Position],3,[])');
    plotTrack(trp,trPos);
    plotTrack(zoomedpp,reshape([platforms.Position],3,[])');
    plotTrack(zoomedtrp,trPos,trIDs);
    drawnow

    % Update the platform positions.
    for i = 1:nPl
        platforms(i).Position = platforms(i).Position + platforms(i).Velocity;
    end
end
disp("Scenario done. All tracks are now deleted." + newline)
clearData(pp)
clearData(trp)
clearData(zoomedpp)
clearData(zoomedtrp)
set(tp.Parent.Parent.Parent,'Visible','off') % Prevent excessive snapshots
drawnow
end

predictedEuclidean

Функция вычисляет Евклидово расстояние между измеренными положениями от обнаружений и предсказанными положениями от дорожек.

function euclidDist = predictedEuclidean(tracks,detections,positionSelector)
% This is a helper function to run the tracker and display the results. It
% may be removed in the future.

if isempty(tracks) || isempty(detections)
    euclidDist = zeros(numel(tracks),numel(detections));
    return
end

predictedStates = [tracks.State];
predictedPositions = positionSelector * predictedStates;
dets = [detections{:}];
measuredPositions = [dets.Measurement];
euclidDist = zeros(numel(tracks),numel(detections));
for i = 1:numel(detections)
    diffs = bsxfun(@minus, predictedPositions',measuredPositions(:,i)');
    euclidDist(:,i) = sqrt(sum((diffs .* diffs),2));
end
end

assignmentMetricsSummary

Функция отображает метрики назначения клавиш в табличной форме.

function assignmentMetricsSummary(trkSummary,truSummary)
trkSummary = rmfield(trkSummary, {'TotalSwapCount','TotalDivergenceCount',...
    'TotalDivergenceLength','MaxRedundancyCount','TotalRedundancyCount',...
    'MaxRedundancyLength','TotalRedundancyLength'});
truSummary = rmfield(truSummary, {'TotalEstablishmentLength','TotalBreakCount',...
    'MaxBreakLength','TotalBreakLength'});
trkTable = struct2table(trkSummary);
truTable = struct2table(truSummary);
disp("Track assignment metrics summary:")
disp(trkTable)
disp("Truth assignment metrics summary:")
disp(truTable)
end