exponenta event banner

Учебное пособие по отслеживанию нескольких объектов

В этом примере показано, как выполнять автоматическое обнаружение и отслеживание движущихся объектов в видео на основе движения. Он упрощает пример отслеживания нескольких объектов на основе движения и использует multiObjectTracker доступно в Toolbox™ автоматизированного вождения.

Обнаружение движущихся объектов и отслеживание движения являются важными компонентами многих приложений компьютерного зрения, включая распознавание активности, мониторинг движения и автомобильную безопасность. Проблему отслеживания объектов на основе движения можно разделить на две части:

  1. Обнаружение движущихся объектов в каждом кадре

  2. Отслеживание движущихся объектов из кадра в кадр

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

Сопровождение движущихся объектов от кадра к кадру осуществляется multiObjectTracker объект, ответственный за следующее:

  1. Назначение обнаружений дорожкам.

  2. Инициализация новых дорожек на основе неназначенных обнаружений. Все дорожки инициализируются как 'Tentative', учитывая возможность того, что они стали результатом ложного обнаружения.

  3. Подтверждение дорожек, если они имеют более чем М назначенных обнаружений в N кадрах.

  4. Обновление существующих дорожек на основе назначенных обнаружений.

  5. Укрощение (прогнозирование) существующих неназначенных трасс.

  6. Удаление дорожек, если они слишком долго оставались неназначенными.

Назначение обнаружений одному и тому же объекту основано исключительно на движении. Движение каждой дорожки оценивается фильтром Калмана. Фильтр предсказывает местоположение дорожки в каждом кадре и определяет вероятность назначения каждого обнаружения каждой дорожке. Чтобы инициализировать создаваемый фильтр, используйте FilterInitializationFcn имущества multiObjectTracker.

Дополнительные сведения см. в разделе Отслеживание нескольких объектов.

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

function MultipleObjectTrackingExample()

% Create objects used for reading video and displaying the results.
videoObjects = setupVideoObjects('atrium.mp4');

% Create objects used for detecting objects in the foreground of the video.
minBlobArea = 400; % Minimum blob size, in pixels, to be considered as a detection
detectorObjects = setupDetectorObjects(minBlobArea);

Создание многообъектного трекера

При создании multiObjectTracker, рассмотрим следующее:

  1. FilterInitializationFcnВероятные модели движения и измерения. В этом случае ожидается, что объекты будут иметь движение с постоянной скоростью. initDemoFilter функция настраивает линейный фильтр Калмана для отслеживания движения. Дополнительные сведения см. в разделе Определение фильтра Калмана.

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

  3. DeletionThresholdКак долго ведется трек до удаления. В этом случае, поскольку видео имеет 30 кадров в секунду, разумное значение составляет около 0,75 секунды (22 кадра).

  4. ConfirmationThresholdПараметры, контролирующие подтверждение пути. Дорожка инициализируется с каждым неназначенным обнаружением. Некоторые из этих обнаружений могут быть ложными, поэтому изначально все треки являются 'Tentative'. Для подтверждения дорожки она должна быть обнаружена, по меньшей мере, в M из N кадров. Выбор M и N зависит от видимости объектов. В этом примере предполагается видимость 6 из 10 кадров.

tracker = multiObjectTracker(...
    'FilterInitializationFcn', @initDemoFilter, ...
    'AssignmentThreshold', 30, ...
    'DeletionThreshold', 22, ...
    'ConfirmationThreshold', [6 10] ...
    );

Определение фильтра Калмана

При определении фильтра отслеживания движения выполните следующие действия.

Шаг 1: Определение модели движения и состояния

В этом примере используется модель постоянной скорости в 2-D прямоугольном кадре.

  1. Состояние: [x;vx;y;vy].

  2. Матрица модели перехода состояния A = [1 dt 0 0; 0 1 0 0; 0 0 1 dt; 0 0 0 1].

  3. Предположим, что dt = 1.

Шаг 2: Определение шума процесса

Шум процесса представляет части процесса, которые не учитываются в модели. Например, в модели с постоянной скоростью ускорение игнорируется.

Шаг 3: Определение модели измерения

В этом примере только позиция ([x;y]) измеряется. Таким образом, модель измерения H = [1 0 0 0; 0 0 1 0].

Примечание.Для предварительной настройки этих параметров определите 'MotionModel' свойство как '2D Constant Velocity'.

Шаг 4: Инициализация вектора состояния на основе измерения датчика

В этом примере, поскольку измерение [x;y] и государство [x;vx;y;vy], инициализация вектора состояния является простой. Поскольку нет измерения скорости, инициализируйте vx и vy компоненты в 0.

Шаг 5: определение ковариации начального состояния

В этом примере измерения являются довольно шумными, поэтому определяем ковариацию начального состояния как достаточно большую: stateCov = diag([50, 50, 50, 50])

Шаг 6: Создание правильного фильтра

В этом примере все модели являются линейными, поэтому используйте trackingKF в качестве фильтра слежения.

    function filter = initDemoFilter(detection)
    % Initialize a Kalman filter for this example.

    % Define the initial state.
    state = [detection.Measurement(1); 0; detection.Measurement(2); 0];

    % Define the initial state covariance.
    stateCov = diag([50, 50, 50, 50]);

    % Create the tracking filter.
    filter = trackingKF('MotionModel', '2D Constant Velocity', ...
        'State', state, ...
        'StateCovariance', stateCov, ...
        'MeasurementNoise', detection.MeasurementNoise(1:2,1:2) ...
        );
    end

Следующий цикл запускает видеоклип, обнаруживает движущиеся объекты в видео и отслеживает их по видеокадрам.

% Count frames to create a sense of time.
frameCount = 0;
while hasFrame(videoObjects.reader)
    % Read a video frame and detect objects in it.
    frameCount = frameCount + 1;                                % Promote frame count
    frame = readFrame(videoObjects.reader);                     % Read frame
    [detections, mask] = detectObjects(detectorObjects, frame); % Detect objects in video frame

    % Run the tracker on the preprocessed detections.
    confirmedTracks = updateTracks(tracker, detections, frameCount);

    % Display the tracking results on the video.
    displayTrackingResults(videoObjects, confirmedTracks, frame, mask);
end

Создание видеообъектов

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

    function videoObjects = setupVideoObjects(filename)
        % Initialize video I/O
        % Create objects for reading a video from a file, drawing the tracked
        % objects in each frame, and playing the video.

        % Create a video file reader.
        videoObjects.reader = VideoReader(filename);

        % Create two video players: one to display the video,
        % and one to display the foreground mask.
        videoObjects.maskPlayer  = vision.VideoPlayer('Position', [20, 400, 700, 400]);
        videoObjects.videoPlayer = vision.VideoPlayer('Position', [740, 400, 700, 400]);
    end

Создание объектов-детекторов

Создание объектов, используемых для обнаружения объектов переднего плана. Использовать minBlobArea для определения размера большого двоичного объекта в пикселях, который считается обнаружением.

  • Увеличение minBlobArea чтобы избежать обнаружения небольших блобов, которые с большей вероятностью будут ложными обнаружениями, или если для одного и того же объекта создается несколько обнаружений из-за частичной окклюзии.

  • Уменьшение minBlobArea если объекты обнаружены слишком поздно или вообще не обнаружены.

    function detectorObjects = setupDetectorObjects(minBlobArea)
        % Create System objects for foreground detection and blob analysis

        % The foreground detector segments moving objects from the
        % background. It outputs a binary mask, where the pixel value of 1
        % corresponds to the foreground and the value of 0 corresponds to
        % the background.

        detectorObjects.detector = vision.ForegroundDetector('NumGaussians', 3, ...
            'NumTrainingFrames', 40, 'MinimumBackgroundRatio', 0.7);

        % Connected groups of foreground pixels are likely to correspond to
        % moving objects.  The blob analysis System object finds such
        % groups (called 'blobs' or 'connected components') and computes
        % their characteristics, such as their areas, centroids, and the
        % bounding boxes.

        detectorObjects.blobAnalyzer = vision.BlobAnalysis('BoundingBoxOutputPort', true, ...
            'AreaOutputPort', true, 'CentroidOutputPort', true, ...
            'MinimumBlobArea', minBlobArea);
    end

Обнаружение объектов

detectObjects функция возвращает центроиды и ограничивающие рамки обнаруженных объектов в виде списка objectDetection объекты. Этот список можно предоставить в качестве входных данных для multiObjectTracker. detectObjects функция также возвращает двоичную маску, которая имеет тот же размер, что и входной кадр. Пикселы со значением 1 соответствуют переднему плану. Пикселы со значением 0 соответствуют фону.

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

При создании objectDetection список, frameCount служит в качестве временного ввода, а центроиды обнаруженных блобов служат в качестве измерения. Список также имеет две необязательные пары имя-значение:

  • MeasurementNoise - Обнаружение больших двоичных объектов является шумным, и этот пример определяет большое значение шума измерения.

  • ObjectAttributes - Обнаруженные ограничивающие рамки, передаваемые на дисплей дорожки, добавляются к этому аргументу.

    function [detections, mask] = detectObjects(detectorObjects, frame)
        % Expected uncertainty (noise) for the blob centroid.
        measurementNoise = 100*eye(2);
        % Detect foreground.
        mask = detectorObjects.detector.step(frame);

        % Apply morphological operations to remove noise and fill in holes.
        mask = imopen(mask, strel('rectangle', [6, 6]));
        mask = imclose(mask, strel('rectangle', [50, 50]));
        mask = imfill(mask, 'holes');

        % Perform blob analysis to find connected components.
        [~, centroids, bboxes] = detectorObjects.blobAnalyzer.step(mask);

        % Formulate the detections as a list of objectDetection objects.
        numDetections = size(centroids, 1);
        detections = cell(numDetections, 1);
        for i = 1:numDetections
            detections{i} = objectDetection(frameCount, centroids(i,:), ...
                'MeasurementNoise', measurementNoise, ...
                'ObjectAttributes', {bboxes(i,:)});
        end
    end

Показать результаты отслеживания

displayTrackingResults рисует ограничивающую рамку и идентификатор метки для каждой дорожки на видеокадре и маске переднего плана. Затем он отображает кадр и маску в соответствующих видеопроигрывателях.

    function displayTrackingResults(videoObjects, confirmedTracks, frame, mask)
        % Convert the frame and the mask to uint8 RGB.
        frame = im2uint8(frame);
        mask = uint8(repmat(mask, [1, 1, 3])) .* 255;

        if ~isempty(confirmedTracks)
            % Display the objects. If an object has not been detected
            % in this frame, display its predicted bounding box.
            numRelTr = numel(confirmedTracks);
            boxes = zeros(numRelTr, 4);
            ids = zeros(numRelTr, 1, 'int32');
            predictedTrackInds = zeros(numRelTr, 1);
            for tr = 1:numRelTr
                % Get bounding boxes.
                boxes(tr, :) = confirmedTracks(tr).ObjectAttributes{1}{1};

                % Get IDs.
                ids(tr) = confirmedTracks(tr).TrackID;

                if confirmedTracks(tr).IsCoasted
                    predictedTrackInds(tr) = tr;
                end
            end

            predictedTrackInds = predictedTrackInds(predictedTrackInds > 0);

            % Create labels for objects that display the predicted rather
            % than the actual location.
            labels = cellstr(int2str(ids));

            isPredicted = cell(size(labels));
            isPredicted(predictedTrackInds) = {' predicted'};
            labels = strcat(labels, isPredicted);

            % Draw the objects on the frame.
            frame = insertObjectAnnotation(frame, 'rectangle', boxes, labels);

            % Draw the objects on the mask.
            mask = insertObjectAnnotation(mask, 'rectangle', boxes, labels);
        end

        % Display the mask and the frame.
        videoObjects.maskPlayer.step(mask);
        videoObjects.videoPlayer.step(frame);
    end
end

Резюме

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

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

Можно уменьшить вероятность ошибок отслеживания, используя более сложную модель движения, такую как постоянное ускорение или постоянный поворот. Для этого попробуйте определить другой фильтр отслеживания, например trackingEKF или trackingUKF.

См. также

Объекты

Связанные темы