В этом примере показано, как обнаружить людей в видео, снятом калиброванной стереофотоаппаратом, и определить их расстояния от камеры.
Загрузите stereoParameters
объект, который является результатом калибровки камеры с помощью stereoCameraCalibrator
приложение или estimateCameraParameters
функция.
% Load the stereoParameters object. load('handshakeStereoParams.mat'); % Visualize camera extrinsics. showExtrinsics(stereoParams);
Создайте системные объекты для чтения и отображения видео.
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');
В выпрямленной стерео изображениях любая пара соответствующих точек расположена в одной пиксельной строке. Для каждого пикселя в левом изображении вычислите расстояние до соответствующего пикселя в правом изображении. Это расстояние называется несоответствием, и оно пропорционально расстоянию соответствующей мировой точки от камеры.
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 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
% Clean up
release(player);
Этот пример показал, как локализовать пешеходов в 3-D с помощью калиброванной стереофотоаппарата.
[1] G. Bradski and A. Kaehler, «Learning OpenCV: Компьютерное зрение with the OpenCV Library», O'Reilly, Sebastopol, CA, 2008.
[2] Даляль, Н. и триггеры, Б., Гистограммы ориентированных градиентов для обнаружения человека. CVPR 2005.