이 번역 페이지는 최신 내용을 담고 있지 않습니다. 최신 내용을 영문으로 보려면 여기를 클릭하십시오.
스테레오 비디오에서 깊이 추정
이 예제에서는 보정된 스테레오 카메라로 촬영한 비디오에서 사람을 검출하고 카메라와의 거리를 확인하는 방법을 보여줍니다.
스테레오 카메라의 파라미터 불러오기
stereoParameters
객체를 불러옵니다. 이 객체는 stereoCameraCalibrator
앱 또는 estimateCameraParameters
함수를 사용하여 카메라를 보정한 결과입니다.
% Load the stereoParameters object. load('handshakeStereoParams.mat'); % Visualize camera extrinsics. showExtrinsics(stereoParams);
비디오 파일 리더와 비디오 플레이어 만들기
비디오를 읽고 표시하기 위한 System object를 만듭니다.
videoFileLeft = 'handshake_left.avi'; videoFileRight = 'handshake_right.avi'; readerLeft = VideoReader(videoFileLeft); readerRight = VideoReader(videoFileRight); player = vision.VideoPlayer('Position', [20,200,740 560]);
비디오 프레임 읽기 및 편위수정하기
시차를 계산하고 3차원 장면을 복원하기 위해 왼쪽 카메라와 오른쪽 카메라의 프레임을 편위수정해야 합니다. 편위수정된 영상은 에피폴라 선을 가지며, 행 단위로 정렬되어 있습니다. 이는 매칭 점의 검색 공간을 1차원으로 줄여 시차 계산을 단순화합니다. 편위수정된 영상들을 하나의 입체사진(anaglyph)으로 결합할 수도 있습니다. 이러한 입체사진을 스테레오 적청(red-cyan) 안경으로 보면 3차원 효과가 나타납니다.
frameLeft = readFrame(readerLeft); frameRight = readFrame(readerRight); [frameLeftRect, frameRightRect, reprojectionMatrix] = ... rectifyStereoImages(frameLeft, frameRight, stereoParams); figure; imshow(stereoAnaglyph(frameLeftRect, frameRightRect)); title('Rectified Video Frames');
시차 계산하기
편위수정된 스테레오 영상에서 대응하는 점들의 쌍은 동일한 픽셀 행에 위치합니다. 왼쪽 영상의 각 픽셀에 대해, 오른쪽 영상에서 대응하는 픽셀까지의 거리를 계산합니다. 이 거리를 시차(disparity)라고 하며, 카메라로부터 대응하는 세계 좌표 점까지의 거리에 비례합니다.
frameLeftGray = im2gray(frameLeftRect); frameRightGray = im2gray(frameRightRect); disparityMap = disparitySGM(frameLeftGray, frameRightGray); figure; imshow(disparityMap, [0, 64]); title('Disparity Map'); colormap jet colorbar
3차원 장면 복원하기
시차 지도의 각 픽셀에 대응하는 점들의 3차원 세계 좌표를 복원합니다.
points3D = reconstructScene(disparityMap, reprojectionMatrix); % 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
System object를 사용하여 사람을 검출합니다.
% 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차원 세계 좌표를 구하고 중심에서 카메라까지의 거리(단위: 미터)를 계산합니다.
% 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 = im2gray(frameLeftRect); frameRightGray = im2gray(frameRightRect); % Compute disparity. disparityMap = disparitySGM(frameLeftGray, frameRightGray); % Reconstruct 3-D scene. points3D = reconstructScene(disparityMap, reprojectionMatrix); 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차원에서 보행자의 위치를 확인하는 방법을 다루었습니다.
참고 문헌
[1] G. Bradski and A. Kaehler, "Learning OpenCV : Computer Vision with the OpenCV Library," O'Reilly, Sebastopol, CA, 2008.
[2] Dalal, N. and Triggs, B., Histograms of Oriented Gradients for Human Detection. CVPR 2005.