Оценка глубины из стерео видео

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

Загрузка параметров стереофотоаппарата

Загрузите stereoParameters объект, который является результатом калибровки камеры с помощью stereoCameraCalibrator приложение или estimateCameraParameters функция.

% Load the stereoParameters object.
load('handshakeStereoParams.mat');

% Visualize camera extrinsics.
showExtrinsics(stereoParams);

Figure contains an axes. The axes with title Extrinsic Parameters Visualization contains 32 objects of type patch, text, line.

Создайте видео Файла читателей и видеоплеер

Создайте системные объекты для чтения и отображения видео.

videoFileLeft = 'handshake_left.avi';
videoFileRight = 'handshake_right.avi';

readerLeft = VideoReader(videoFileLeft);
readerRight = VideoReader(videoFileRight);
player = vision.VideoPlayer('Position', [20,200,740 560]);

Чтение и исправление видеокадров

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

frameLeft = readFrame(readerLeft);
frameRight = readFrame(readerRight);

[frameLeftRect, frameRightRect] = ...
    rectifyStereoImages(frameLeft, frameRight, stereoParams);

figure;
imshow(stereoAnaglyph(frameLeftRect, frameRightRect));
title('Rectified Video Frames');

Figure contains an axes. The axes with title Rectified Video Frames contains an object of type image.

Вычисление несоответствия

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

frameLeftGray  = rgb2gray(frameLeftRect);
frameRightGray = rgb2gray(frameRightRect);
    
disparityMap = disparitySGM(frameLeftGray, frameRightGray);
figure;
imshow(disparityMap, [0, 64]);
title('Disparity Map');
colormap jet
colorbar

Figure contains an axes. The axes with title Disparity Map contains an object of type image.

Восстановите 3-D сцену

Восстановите координаты мира 3-D точек, соответствующих каждому пикселю, из карты расхождения.

points3D = reconstructScene(disparityMap, stereoParams);

% Convert to meters and create a pointCloud object
points3D = points3D ./ 1000;
ptCloud = pointCloud(points3D, 'Color', frameLeftRect);

% Create a streaming point cloud viewer
player3D = pcplayer([-3, 3], [-3, 3], [0, 8], 'VerticalAxis', 'y', ...
    'VerticalAxisDir', 'down');

% Visualize the point cloud
view(player3D, ptCloud);

Figure Point Cloud Player contains an axes. The axes contains an object of type scatter.

Обнаружение людей в левом изображении

Используйте vision.PeopleDetector системный объект для обнаружения людей.

% Create the people detector object. Limit the minimum object size for
% speed.
peopleDetector = vision.PeopleDetector('MinSize', [166 83]);

% Detect people.
bboxes = peopleDetector.step(frameLeftGray);

Определите расстояние между каждым человеком и камерой

Найдите 3-D мировые координаты центроида каждого обнаруженного человека и вычислите расстояние от центроида до камеры в метрах.

% Find the centroids of detected people.
centroids = [round(bboxes(:, 1) + bboxes(:, 3) / 2), ...
    round(bboxes(:, 2) + bboxes(:, 4) / 2)];

% Find the 3-D world coordinates of the centroids.
centroidsIdx = sub2ind(size(disparityMap), centroids(:, 2), centroids(:, 1));
X = points3D(:, :, 1);
Y = points3D(:, :, 2);
Z = points3D(:, :, 3);
centroids3D = [X(centroidsIdx)'; Y(centroidsIdx)'; Z(centroidsIdx)'];

% Find the distances from the camera in meters.
dists = sqrt(sum(centroids3D .^ 2));
    
% Display the detected people and their distances.
labels = cell(1, numel(dists));
for i = 1:numel(dists)
    labels{i} = sprintf('%0.2f meters', dists(i));
end
figure;
imshow(insertObjectAnnotation(frameLeftRect, 'rectangle', bboxes, labels));
title('Detected People');

Figure contains an axes. The axes with title Detected People contains an object of type image.

Обработка остальной части видео

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

while hasFrame(readerLeft) && hasFrame(readerRight)
    % Read the frames.
    frameLeft = readFrame(readerLeft);
    frameRight = readFrame(readerRight);
    
    % Rectify the frames.
    [frameLeftRect, frameRightRect] = ...
        rectifyStereoImages(frameLeft, frameRight, stereoParams);
    
    % Convert to grayscale.
    frameLeftGray  = rgb2gray(frameLeftRect);
    frameRightGray = rgb2gray(frameRightRect);
    
    % Compute disparity. 
    disparityMap = disparitySGM(frameLeftGray, frameRightGray);
    
    % Reconstruct 3-D scene.
    points3D = reconstructScene(disparityMap, stereoParams);
    points3D = points3D ./ 1000;
    ptCloud = pointCloud(points3D, 'Color', frameLeftRect);
    view(player3D, ptCloud);
    
    % Detect people.
    bboxes = peopleDetector.step(frameLeftGray);
    
    if ~isempty(bboxes)
        % Find the centroids of detected people.
        centroids = [round(bboxes(:, 1) + bboxes(:, 3) / 2), ...
            round(bboxes(:, 2) + bboxes(:, 4) / 2)];
        
        % Find the 3-D world coordinates of the centroids.
        centroidsIdx = sub2ind(size(disparityMap), centroids(:, 2), centroids(:, 1));
        X = points3D(:, :, 1);
        Y = points3D(:, :, 2);
        Z = points3D(:, :, 3);
        centroids3D = [X(centroidsIdx), Y(centroidsIdx), Z(centroidsIdx)];
        
        % Find the distances from the camera in meters.
        dists = sqrt(sum(centroids3D .^ 2, 2));
        
        % Display the detect people and their distances.
        labels = cell(1, numel(dists));
        for i = 1:numel(dists)
            labels{i} = sprintf('%0.2f meters', dists(i));
        end
        dispFrame = insertObjectAnnotation(frameLeftRect, 'rectangle', bboxes,...
            labels);
    else
        dispFrame = frameLeftRect;
    end
    
    % Display the frame.
    step(player, dispFrame);
end

Figure Point Cloud Player contains an axes. The axes contains an object of type scatter.

Figure contains an axes. The axes with title Detected People contains an object of type image.

% Clean up
release(player);

Figure Video Player contains an axes and other objects of type uiflowcontainer, uimenu, uitoolbar. The axes contains an object of type image.

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

Этот пример показал, как локализовать пешеходов в 3-D с помощью калиброванной стереофотоаппарата.

Ссылки

[1] G. Bradski and A. Kaehler, «Learning OpenCV: Компьютерное зрение with the OpenCV Library», O'Reilly, Sebastopol, CA, 2008.

[2] Даляль, Н. и триггеры, Б., Гистограммы ориентированных градиентов для обнаружения человека. CVPR 2005.