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

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

Загрузите параметры стереофотоаппарата

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

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

% Visualize camera extrinsics.
showExtrinsics(stereoParams);

Figure contains an axes object. The axes object 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 сцену. Исправленные изображения имеют горизонталь epipolar линии и выравниваются строкой. Это упрощает расчет несоизмеримости путем сокращения пространства поиска для соответствия с точками к одной размерности. Исправленные изображения могут также быть объединены в анаглиф, который может быть просмотрен с помощью красно-голубых стекол стерео, чтобы видеть 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 object. The axes object 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 object. The axes object 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 object. The axes object 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 object. The axes object 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 object. The axes object contains an object of type scatter.

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

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

% Clean up
release(player);

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

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

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

Ссылки

[1] Г. Брадский и А. Кэехлер, "изучение OpenCV: компьютерное зрение с библиотекой OpenCV", О'Райли, Севастополем, CA, 2008.

[2] Dalal, N. и Triggs, B., гистограммы ориентированных градиентов для человеческого обнаружения. CVPR 2005.