基于立体视频的深度估计
这个例子展示了如何检测用校准的立体摄像机拍摄的视频中的人,并确定他们与摄像机的距离。
加载立体声摄像机参数
加载stereoParameters
对象,该对象是使用stereoCameraCalibrator
应用程序或estimateCameraParameters
函数。
加载立体参数对象。负载(“handshakeStereoParams.mat”);可视化相机外观。showExtrinsics (stereoParams);
创建视频文件阅读器和视频播放器
创建用于读取和显示视频的系统对象。
videoFileLeft =“handshake_left.avi”;videoFileRight =“handshake_right.avi”;readerLeft = VideoReader (videoFileLeft);readerRight = VideoReader (videoFileRight);球员=愿景。放像机(“位置”560年[20200740]);
读取和纠正视频帧
为了计算视差和重建3d场景,必须对来自左右相机的帧进行校正。校正后的图像具有水平极线,并且行对齐。通过将匹配点的搜索空间减少到一维,这简化了视差的计算。校正后的图像也可以组合成浮雕,可以使用立体红青色眼镜观看3d效果。
frameLeft = readFrame (readerLeft);frameRight = readFrame (readerRight);[frameLeftRect, frameRightRect, reprojectionMatrix] =...rectifyStereoImages (frameLeft frameRight stereoParams);图;imshow (stereoAnaglyph (frameLeftRect frameRightRect));标题(纠正视频帧的);
计算差异
在整流立体图像中,任何一对对应点都位于同一像素行上。对于左边图像中的每个像素,计算到右边图像中相应像素的距离。这个距离叫做视差,它与对应的世界点到相机的距离成正比。
frameLeftGray = rgb2gray (frameLeftRect);frameRightGray = rgb2gray (frameRightRect);distitymap = distitysgm (frameLeftGray, frameRightGray);图;, 64年imshow (disparityMap [0]);标题(“差距地图”);colormap飞机colorbar
重建3d场景
从视差图中重建每个像素对应点的三维世界坐标。
points3D = reconstructScene(distitymap, reprojectionMatrix);转换为米并创建pointCloud对象points3D = points3D ./ 1000;ptCloud = pointCloud (points3D,“颜色”, frameLeftRect);创建流点云查看器player3D = pcplayer([-3, 3], [-3, 3], [0,8],“VerticalAxis”,“y”,...“VerticalAxisDir”,“下来”);形象化点云视图(player3D ptCloud);
检测左边图像中的人
使用愿景。PeopleDetector
系统对象用于检测人员。
创建人员检测器对象。限制最小对象大小%的速度。peopleDetector =愿景。PeopleDetector (“MinSize”83年[166]);%检测人。bboxes = peopleDetector.step (frameLeftGray);
确定每个人到相机的距离
求出每个被检测人质心的三维世界坐标,计算质心到摄像机的距离,单位为米。
找到被检测到的人的中心点。圆心= [round(bboxes(:, 1) + bboxes(:, 3) / 2),...Round (bboxes(:, 2) + bboxes(:, 4) / 2)];求质心的三维世界坐标。。centroidsIdx = sub2ind(size(disparityMap), centroids(:, 2), centroids(:, 1));X = points3D(:,:, 1);Y = points3D(:,:, 2);Z = points3D(:,:, 3);centroids3D = [X (centroidsIdx) ';Y (centroidsIdx) ';Z (centroidsIdx)];找出到相机的距离,单位为米。dist = sqrt(sum(centroids3D .^ 2));显示被检测到的人和他们的距离。标签= cell(1, numel(dist));为I = 1:numel(dist) labels{I} = sprintf(“% 0.2 f米”距离(我));结束图;imshow (insertObjectAnnotation (frameLeftRect,“矩形”、bboxes标签);标题(检测到人的);
处理视频的其余部分
应用上面描述的步骤来检测人,并在视频的每一帧中测量他们到摄像机的距离。
而hasFrame (readerLeft) & & hasFrame (readerRight)读帧。frameLeft = readFrame (readerLeft);frameRight = readFrame (readerRight);校正帧。[frameLeftRect, frameRightRect] =...rectifyStereoImages (frameLeft frameRight stereoParams);%转换为灰度。frameLeftGray = rgb2gray (frameLeftRect);frameRightGray = rgb2gray (frameRightRect);%计算差异。distitymap = distitysgm (frameLeftGray, frameRightGray);重建3d场景。points3D = reconstructScene(distitymap, reprojectionMatrix);points3D = points3D ./ 1000;ptCloud = pointCloud (points3D,“颜色”, frameLeftRect);视图(player3D ptCloud);%检测人。bboxes = peopleDetector.step (frameLeftGray);如果~ isempty (bboxes)找到被检测到的人的中心点。圆心= [round(bboxes(:, 1) + bboxes(:, 3) / 2),...Round (bboxes(:, 2) + bboxes(:, 4) / 2)];求质心的三维世界坐标。。centroidsIdx = sub2ind(size(disparityMap), centroids(:, 2), centroids(:, 1));X = points3D(:,:, 1);Y = points3D(:,:, 2);Z = points3D(:,:, 3);centroids3D = [X(centroidsIdx), Y(centroidsIdx), Z(centroidsIdx)];找出到相机的距离,单位为米。dist = sqrt(sum(centroids3D .^ 2, 2));显示检测人员和他们的距离。标签= cell(1, numel(dist));为I = 1:numel(dist) labels{I} = sprintf(“% 0.2 f米”距离(我));结束dispFrame = insertObjectAnnotation (frameLeftRect,“矩形”bboxes,...标签);其他的dispFrame = frameLeftRect;结束%显示帧。步骤(球员,dispFrame);结束
%清理释放(球员);
总结
这个例子展示了如何使用校准的立体相机在3-D中定位行人。
参考文献
[1] G. Bradski和A. Kaehler,“学习OpenCV:使用OpenCV库的计算机视觉”,O'Reilly,塞瓦斯托波尔,CA, 2008。
[2] Dalal, N.和Triggs, B.,面向梯度的人体检测直方图。CVPR 2005。