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

В этом примере показано, как использовать 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: 8.3108
Step 1 time: 3.7554
Step 2 time: 15.3029
Step 3 time: 14.1099
Step 4 time: 14.3506
Step 5 time: 14.3963

All steps from now are without detections.
Step 6 time: 0.53103
Step 7 time: 0.52582
Step 8 time: 0.50639
Step 9 time: 0.50909
Step 10 time: 0.16034
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: 6.5846
Step 1 time: 3.5863
Step 2 time: 3.4095
Step 3 time: 2.9347
Step 4 time: 2.8555
Step 5 time: 2.9397

All steps from now are without detections.
Step 6 time: 0.51446
Step 7 time: 0.52277
Step 8 time: 0.54865
Step 9 time: 0.50941
Step 10 time: 0.19085
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: 6.559
Step 1 time: 3.4394
Step 2 time: 1.7852
Step 3 time: 1.474
Step 4 time: 1.5312
Step 5 time: 1.5152

All steps from now are without detections.
Step 6 time: 0.60809
Step 7 time: 0.61374
Step 8 time: 0.616
Step 9 time: 0.63798
Step 10 time: 0.22762
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: 6.494
Step 1 time: 3.5346
Step 2 time: 1.894
Step 3 time: 3.1192
Step 4 time: 3.1212
Step 5 time: 3.1458

All steps from now are without detections.
Step 6 time: 0.61109
Step 7 time: 0.62456
Step 8 time: 0.61849
Step 9 time: 0.60604
Step 10 time: 0.22303
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.097531
Step 1 time: 3.4684
Step 2 time: 1.6592
Step 3 time: 3.1429
Step 4 time: 3.1274
Step 5 time: 3.0994

All steps from now are without detections.
Step 6 time: 0.63232
Step 7 time: 0.61857
Step 8 time: 0.61433
Step 9 time: 0.60698
Step 10 time: 0.25301
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