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

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

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

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

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

% Visualize camera extrinsics.
showExtrinsics(stereoParams);

Создайте средства чтения видеофайла и видеоплеер

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

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

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

Считайте и исправьте видеокадры

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

frameLeft = readerLeft.step();
frameRight = readerRight.step();

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

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

Вычислите несоизмеримость

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

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

Восстановите 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);

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

Используйте 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');

Остальная часть процесса видео

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

while ~isDone(readerLeft) && ~isDone(readerRight)
    % Read the frames.
    frameLeft = readerLeft.step();
    frameRight = readerRight.step();
    
    % 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

% Clean up.
reset(readerLeft);
reset(readerRight);
release(player);

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

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

Ссылки

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

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