Отследите несколько автомобилей Используя камеру

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

Обзор

Automated Driving Toolbox™ обеспечивает предварительно обученные детекторы автомобиля и мультиобъектное средство отслеживания, чтобы упростить автомобили отслеживания вокруг автомобиля, оборудованного датчиком. Детекторы автомобиля основаны на функциях ACF и Более быстром R-CNN, основанном на глубоком обучении методе обнаружения объектов. Детекторами можно легко обменяться, чтобы видеть их эффект на отслеживание транспортных средств.

Рабочий процесс отслеживания состоит из следующих шагов:

  1. Задайте камеру intrinsics и положение монтирования камеры.

  2. Загрузите и сконфигурируйте предварительно обученный детектор автомобиля.

  3. Настройте мультиобъектное средство отслеживания.

  4. Запустите детектор для каждого кадра видео.

  5. Обновите средство отслеживания с результатами обнаружения.

  6. Отобразите результаты отслеживания в видео.

Сконфигурируйте детектор автомобиля и мультиобъектное средство отслеживания

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

% Load the monoCamera object that contains the camera information.
d = load('FCWDemoMonoCameraSensor.mat', 'sensor');

% Load a pretrained ACF vehicle detector. The ACF detector uses "Aggregate
% Channel Features", which is fast to compute in practice. The 'full-view'
% model is trained on images of the front, rear, left, and right side of
% vehicles.
detector = vehicleDetectorACF('full-view');

Чтобы попробовать Более быстрый детектор автомобиля R-CNN, используйте vehicleDetectorFasterRCNN вместо этого. Этот детектор требует лицензии Deep Learning Toolbox™.

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

% The width of common vehicles is between 1.5 to 2.5 meters. Only a
% bounding box of width within this range is considered as a detection
% candidate in image.
vehicleWidth = [1.5, 2.5];

% Configure the detector using the monoCamera sensor and desired width.
detector = configureDetectorMonoCamera(detector, d.sensor, vehicleWidth);

% Initialize an multi-object tracker including setting the filter,
% the detection-to-track assignment threshold, the coasting and
% confirmation parameters. You can find the |setupTracker| function at the
% end of this example.
[tracker, positionSelector] = setupTracker();

Отследите автомобили в видео

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

% Setup Video Reader and Player
videoFile   = '05_highway_lanechange_25s.mp4';
videoReader = VideoReader(videoFile);
videoPlayer = vision.DeployableVideoPlayer();

currentStep = 0;
snapshot = [];
snapTimeStamp = 120;
cont = hasFrame(videoReader);
while cont
    % Update frame counters.
    currentStep = currentStep + 1;
        
    % Read the next frame.
    frame = readFrame(videoReader);
    
    % Run the detector and package the returned results into an object
    % required by multiObjectTracker.  You can find the |detectObjects|
    % function at the end of this example.
    detections = detectObjects(detector, frame, currentStep);
       
    % Using the list of objectDetections, return the tracks, updated for
    % 'currentStep' time.
    confirmedTracks = updateTracks(tracker, detections, currentStep);
    
    % Remove the tracks for vehicles that are far away.
    confirmedTracks = removeNoisyTracks(confirmedTracks, positionSelector, d.sensor.Intrinsics.ImageSize);
    
    % Insert tracking annotations.
    frameWithAnnotations = insertTrackBoxes(frame, confirmedTracks, positionSelector, d.sensor);

    % Display the annotated frame.    
    videoPlayer(frameWithAnnotations);  
    
    % Take snapshot for publishing at snapTimeStamp seconds
    if currentStep == snapTimeStamp
        snapshot = frameWithAnnotations;
    end   
    
    % Exit the loop if the video player figure is closed by user.
    cont = hasFrame(videoReader) && isOpen(videoPlayer);
end

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

if ~isempty(snapshot)
    figure
    imshow(snapshot)
end

Рабочий процесс отслеживания, представленный здесь, может быть легко интегрирован в Визуальное Восприятие Используя Монокулярный пример Камеры, где шаг обнаружения автомобиля может быть улучшен со средством отслеживания. Чтобы узнать о дополнительных возможностях отслеживания в Automated Driving Toolbox™, смотрите monoCamera и multiObjectTracker.

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

функция setupTracker создает multiObjectTracker, чтобы отследить несколько объектов с Фильтрами Калмана. Когда создание multiObjectTracker рассматривает следующее:

  • FilterInitializationFcn: вероятное движение и модели измерения. В этом случае объекты, как ожидают, будут иметь постоянное скоростное движение. Смотрите раздел 'Define a Kalman filter'.

  • AssignmentThreshold: Как далеко обнаружения могут упасть от дорожек. Значение по умолчанию для этого параметра равняется 30. Если существуют обнаружения, которые не присвоены дорожкам, но должны быть, увеличить это значение. Если существуют обнаружения, которые присвоены дорожкам, которые слишком далеки, уменьшают это значение. Этот пример использует 50.

  • NumCoastingUpdates: Сколько раз дорожка курсируется перед удалением. Каботажное судоходство является термином, использованным для обновления дорожки без присвоенного обнаружения (предсказание). Значение по умолчанию для этого параметра равняется 5.

  • ConfirmationParameters: параметры для подтверждения дорожки. Новый трек инициализируется с каждым неприсвоенным обнаружением. Некоторые из этих обнаружений могут быть ложными, таким образом, все дорожки инициализируются как Tentative. Чтобы подтвердить дорожку, это должно быть обнаружено, по крайней мере, M времена в обновлениях средства отслеживания N. Выбор M и N зависит от видимости объектов. Этот пример использует значение по умолчанию 3 обнаружений из 5 обновлений.

Выходные параметры setupTracker:

  • tracker - multiObjectTracker, который сконфигурирован для этого случая.

  • positionSelector - Матрица, которая задает, какие элементы Вектора состояния являются положением: position = positionSelector * State

function [tracker, positionSelector] = setupTracker()
    % Create the tracker object.
    tracker = multiObjectTracker('FilterInitializationFcn', @initBboxFilter, ...
        'AssignmentThreshold', 50, ...
        'NumCoastingUpdates', 5, ... 
        'ConfirmationParameters', [3 5]);

    % The State vector is: [x; vx; y; vy; w; vw; h; vh]
    % [x;y;w;h] = positionSelector * State
    positionSelector = [1 0 0 0 0 0 0 0; ...
                        0 0 1 0 0 0 0 0; ...
                        0 0 0 0 1 0 0 0; ...
                        0 0 0 0 0 0 1 0]; 
end

функция initBboxFilter задает Фильтр Калмана, чтобы отфильтровать измерение ограничительной рамки.

function filter = initBboxFilter(Detection)
% Step 1: Define the motion model and state.
%   Use a constant velocity model for a bounding box on the image.
%   The state is [x; vx; y; vy; w; wv; h; hv]
%   The state transition matrix is: 
%       [1 dt 0  0 0  0 0  0;
%        0  1 0  0 0  0 0  0; 
%        0  0 1 dt 0  0 0  0; 
%        0  0 0  1 0  0 0  0; 
%        0  0 0  0 1 dt 0  0; 
%        0  0 0  0 0  1 0  0;
%        0  0 0  0 0  0 1 dt; 
%        0  0 0  0 0  0 0  1]
%   Assume dt = 1. This example does not consider time-variant transition
%   model for linear Kalman filter.
    dt = 1;
    cvel =[1 dt; 0 1];
    A = blkdiag(cvel, cvel, cvel, cvel);
 
% Step 2: Define the process noise. 
%   The process noise represents the parts of the process that the model
%   does not take into account. For example, in a constant velocity model,
%   the acceleration is neglected.
    G1d = [dt^2/2; dt];
    Q1d = G1d*G1d';
    Q = blkdiag(Q1d, Q1d, Q1d, Q1d);
 
% Step 3: Define the measurement model.
%   Only the position ([x;y;w;h]) is measured.
%   The measurement model is
    H = [1 0 0 0 0 0 0 0; ...
         0 0 1 0 0 0 0 0; ...
         0 0 0 0 1 0 0 0; ...
         0 0 0 0 0 0 1 0];
 
% Step 4: Map the sensor measurements to an initial state vector.
%   Because there is no measurement of the velocity, the v components are
%   initialized to 0:
    state = [Detection.Measurement(1); ...
             0; ...
             Detection.Measurement(2); ...
             0; ...
             Detection.Measurement(3); ...
             0; ...
             Detection.Measurement(4); ...
             0];
 
% Step 5: Map the sensor measurement noise to a state covariance.
%   For the parts of the state that the sensor measured directly, use the
%   corresponding measurement noise components. For the parts that the
%   sensor does not measure, assume a large initial state covariance. That way,
%   future detections can be assigned to the track.
    L = 100; % Large value
    stateCov = diag([Detection.MeasurementNoise(1,1), ...
                     L, ...
                     Detection.MeasurementNoise(2,2), ...
                     L, ...
                     Detection.MeasurementNoise(3,3), ...
                     L, ...
                     Detection.MeasurementNoise(4,4), ...
                     L]);
 
% Step 6: Create the correct filter.
%   In this example, all the models are linear, so use trackingKF as the
%   tracking filter.
    filter = trackingKF(...
        'StateTransitionModel', A, ...
        'MeasurementModel', H, ...
        'State', state, ...
        'StateCovariance', stateCov, ... 
        'MeasurementNoise', Detection.MeasurementNoise, ...
        'ProcessNoise', Q);
end

функция detectObjects обнаруживает автомобили в изображении.

function detections = detectObjects(detector, frame, frameCount)
    % Run the detector and return a list of bounding boxes: [x, y, w, h]
    bboxes = detect(detector, frame);
    
    % Define the measurement noise.
    L = 100;
    measurementNoise = [L 0  0  0; ...
                        0 L  0  0; ...
                        0 0 L/2 0; ...
                        0 0  0 L/2];
                    
    % Formulate the detections as a list of objectDetection reports.
    numDetections = size(bboxes, 1);
    detections = cell(numDetections, 1);                      
    for i = 1:numDetections
        detections{i} = objectDetection(frameCount, bboxes(i, :), ...
            'MeasurementNoise', measurementNoise);
    end
end

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

function tracks = removeNoisyTracks(tracks, positionSelector, imageSize)

    if isempty(tracks)
        return
    end
    
    % Extract the positions from all the tracks.
    positions = getTrackPositions(tracks, positionSelector);
    % The track is 'invalid' if the predicted position is about to move out
    % of the image, or if the bounding box is too small.
    invalid = ( positions(:, 1) < 1 | ...
                positions(:, 1) + positions(:, 3) > imageSize(2) | ...
                positions(:, 3) <= 20 | ...
                positions(:, 4) <= 20 );
    tracks(invalid) = [];
end

insertTrackBoxes вставляет ограничительные рамки в изображение и отображает положение дорожки перед автомобилем в мировых модулях.

function I = insertTrackBoxes(I, tracks, positionSelector, sensor)

    if isempty(tracks)
        return
    end

    % Allocate memory.
    labels = cell(numel(tracks), 1);
    % Retrieve positions of bounding boxes.
    bboxes = getTrackPositions(tracks, positionSelector);

    for i = 1:numel(tracks)        
        box = bboxes(i, :);
        
        % Convert to vehicle coordinates using monoCamera object.
        xyVehicle = imageToVehicle(sensor, [box(1)+box(3)/2, box(2)+box(4)]);
        
        labels{i} = sprintf('x=%.1f,y=%.1f',xyVehicle(1),xyVehicle(2));
    end
    
    I = insertObjectAnnotation(I, 'rectangle', bboxes, labels, 'Color', 'yellow', ...
        'FontSize', 10, 'TextBoxOpacity', .8, 'LineWidth', 2);
end

Смотрите также

Функции

Объекты

Похожие темы