Этот пример показывает, как обнаружить людей в видео, снятом с калиброванным стереофотоаппаратом, и определить их расстояния от камеры.
Загрузите объект 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 мировые координаты точек, соответствующих каждому пикселю из карты несоизмеримости.
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.