主要内容

基于立体声视频的深度估计

这个例子展示了如何在用校准的立体摄像机拍摄的视频中检测人物,并确定他们与摄像机的距离。

加载立体摄像机的参数

加载stereoParameters对象,这是使用任意一种方法校准相机的结果stereoCameraCalibratorApp或estimateCameraParameters函数。

加载stereparameters对象。负载(“handshakeStereoParams.mat”);视觉化相机外观。showExtrinsics (stereoParams);

图中包含一个轴对象。标题为Extrinsic Parameters Visualization的axes对象包含32个类型为patch、text、line的对象。

创建视频文件阅读器和视频播放器

创建用于读取和显示视频的系统对象。

videoFileLeft =“handshake_left.avi”;videoFileRight =“handshake_right.avi”;readerLeft = videereader (videofilleft);readerRight = videereader (videoFileRight);玩家=视野。放像机(“位置”, [20,200,740 560]);

读取和校正视频帧

为了计算视差并重建3d场景,必须校正来自左右相机的帧。校正后的图像具有水平的极线,并且行对齐。通过将匹配点的搜索空间缩小到一维,简化了视差的计算。校正后的图像还可以组合成一个浮雕,可以使用立体红青色眼镜观看3d效果。

frameLeft = readFrame(readerLeft);frameRight = readFrame(readerRight);[framereftrect, frameRightRect, reprojectionMatrix] =...rectifyStereoImages(frameLeft, frameRight, stereoParams);图;imshow (stereoAnaglyph (frameLeftRect frameRightRect));标题(“校正视频帧”);

图中包含一个轴对象。标题为“整流视频帧”的axes对象包含一个图像类型的对象。

计算差异

在整流立体图像中,任意一对对应点都位于同一像素行上。对于左边图像中的每个像素,计算到右边图像中相应像素的距离。这个距离称为视差,它与对应的世界点到相机的距离成正比。

frameLeftGray = rgb2gray(frameLeftRect);frameRightGray = rgb2gray(frameRightRect);disparityMap = disparitySGM(frameLeftGray, frameRightGray);图;imshow(disparityMap, [0,64]);标题(“差距地图”);colormap飞机colorbar

图中包含一个轴对象。标题为“视差地图”的axes对象包含一个image类型的对象。

重建三维场景

重建视差图中每个像素对应的点的三维世界坐标。

points3D = reconstructScene(disparityMap, 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”, [166 83]);侦测人。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)];计算到相机的距离(以米为单位)。=√(sum(centroids3D .^ 2));显示检测到的人员及其距离。标签= cell(1,编号(dist));{I} = sprintf(“% 0.2 f米”距离(我));结束图;imshow (insertObjectAnnotation (frameLeftRect,“矩形”,盒子,标签));标题(检测到人的);

图中包含一个轴对象。标题为Detected People的axes对象包含一个image类型的对象。

处理余下的视频

应用上述步骤来检测人物,并在视频的每一帧中测量他们与摄像机的距离。

hasFrame(readerLeft) && hasFrame(readerRight)读取帧。frameLeft = readFrame(readerLeft);frameRight = readFrame(readerRight);整改帧。[frameLeftRect, frameRightRect] =...rectifyStereoImages(frameLeft, frameRight, stereoParams);%转换为灰度。frameLeftGray = rgb2gray(frameLeftRect);frameRightGray = rgb2gray(frameRightRect);计算视差。disparityMap = disparitySGM(frameLeftGray, frameRightGray);重建三维场景。points3D = reconstructScene(disparityMap, 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)];计算到相机的距离(以米为单位)。=√(sum(centroids3D .^ 2,2));显示检测到的人及其距离。标签= cell(1,编号(dist));{I} = sprintf(“% 0.2 f米”距离(我));结束disframe = insertObjectAnnotation(frameeftrect,“矩形”bboxes,...标签);其他的disframe = frameftrect;结束显示帧。步骤(球员,dispFrame);结束

{

%清理释放(球员);

{

总结

这个例子展示了如何使用校准的立体相机在3-D中定位行人。

参考文献

[1] G. Bradski和A. Kaehler,“学习OpenCV:使用OpenCV库的计算机视觉”,O'Reilly,塞瓦斯托波尔,CA, 2008。

[2] Dalal, N.和Triggs, B.,面向人类检测的梯度直方图。CVPR 2005。