exponenta event banner

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

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

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

Загрузить 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] Г. Брадски и А. Келер, «Обучение OpenCV: компьютерное видение с помощью библиотеки OpenCV», O'Reilly, Себастополь, Калифорния, 2008.

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