如何通过立体视觉构建小巧轻便的深度感知系统
有多种 3D 传感器方案来实现深度感知系统,包括立体视觉相机、激光雷达和TOF(飞行时间)相机。每个选择都有其优缺点,其中,嵌入式深度感知立体系统成本低,坚固耐用,适合户外使用,并且能够提供高分辨率的彩色点云。
目前市场上有各种现成的立体感知系统。有时系统工程师需求根据精度、基线(两个相机间距)、视野和分辨率等因素,构建定制系统来满足特定的应用需求。
在本文中,我们首先介绍了立体视觉系统的主要部分,并提供了有关使用硬件组成和开源软件制作定制立体相机的说明。由于此设置专注于嵌入式系统,因此它将实时计算任何场景的深度图,而无需电脑主机。在另一篇文章中,我们将讨论如何在空间较少的情况下构建定制立体视觉系统,以便与电脑主机一起使用。
此类机载处理系统对于另一种应用同样具有巨大效益,那就是对象检测。随着深度学习的发展,在应用程序中添加对象检测功能相对容易,但它需要专用的 GPU 资源,这一点令许多用户望而却步。本文还将讨论如何在省下昂贵的主机 GPU 的情况下将深度学习添加到立体视觉应用程序中。本文的示例代码与章节按立体视觉和深度学习分开,如果您的应用不需要深度学习,请跳过这一部分。
立体视觉概述
立体视觉是通过从两个视角比较场景中的信息,从数字图像中提取 3D 信息。物体在两个图像平面中的相对位置可提供关于物体距离相机的深度的信息。
立体视觉系统概述如图 1 所示,包括以下关键步骤:
- 校准:相机校准包括内部校准和外部校准。内部校准确定图像中心、焦距和失真参数,而外部校准确定相机的 3D 位置。这在许多计算机视觉应用中是至关重要的一步,尤其是在需要有关场景的计量信息(例如深度)时。我们将在下文第 5 节详细讨论校准步骤。
- 纠正:立体纠正是指将图像平面重新投影到与相机中心之间的线平行的公共平面上的过程。纠正后,对应点位于同一行,大大降低了匹配的成本和模糊度。此步骤在提供的代码中完成,用于构建您自己的系统。
- 立体匹配:这是指在左右图像之间匹配像素的过程,从而产生视差图像。提供的代码中将使用半全局匹配 (SGM) 算法来构建您自己的系统。
- 三角测量:三角测量是指在给定 3D 空间中的点投影到两个图像上的情况下确定该点的过程。视差图像将转换为 3D 点云。
图 1:立体视觉系统概述
深度学习概述
深度学习是机器学习的一个子领域,其算法受大脑的结构和功能启发。它模拟人脑的学习能力。深度学习算法可以高效地执行对象识别、分类、分割等复杂操作。此外,深度学习使机器识别图像中的人和对象。我们认为人物检测应用值得研究。训练属于自己的深度学习算法需要大量标记的训练数据,不过,任何人都可以利用开源的预训练模型,加快开发这类应用程序。
深度学习还需要高性能 GPU,Quartet 的 TX2 解决方案具备大型 GPU 的完整能力,但外形尺寸和功耗只有其若干份之一。在 TX2 上运行深度学习模型还具备便携性,非常适合移动机器人检测、避开人员。
设计示例
我们来看一个立体声系统设计示例。以下是移动机器人在具有快速移动物体的动态环境中的应用要求。有关场景大小为 2 m,相机到场景的距离为 3 m,在 3 m 处所需的精度为 1 cm。
有关立体精度的更多详细信息,请参阅本文。深度误差由下式给出:ΔZ=Z²/Bf * Δd,这取决于以下因素:
- Z 是范围
- B 是基线
- f 是以像素为单位的焦距,与相机视野和图像分辨率有关
有多种设计选项可以满足这些要求。根据上述场景大小和距离要求,我们可以确定特定传感器的镜头焦距。结合基线,我们可以使用上述公式计算 3 m 处的预期深度误差,以验证其是否满足精度要求。
图 2 显示了两个选项,使用基线较长的低分辨率相机或基线较短的高分辨率相机。第一个选项是较大的相机,但计算需求较低,而第二个选项是更紧凑的相机,但计算需求较高。对于此应用,我们选择了第二个选项,因为紧凑的尺寸更适合移动机器人,我们可以使用适用于 TX2 的 Quartet 嵌入式解决方案,该解决方案具有强大的板载 GPU 来满足处理需求。
图 2:示例应用的立体声系统设计选项
硬件要求
在本例中,我们使用 IMX273 Sony Pregius 全局快门传感器将两台 Blackfly S 板级 160 万像素相机安装在 12 cm 基线处的 3D 印刷杆上。这两台相机都有类似的 6 mm S 接口镜头。相机使用两条 FPC 电缆连接到“适用于 TX2 的 Quartet 嵌入式解决方案”定制载板。为了同步左右相机以同时捕捉图像,制作了一条连接两个相机的同步电缆。图 3 显示了我们定制的嵌入式立体声系统的前后视图。
图 3:定制嵌入式立体声系统的前后视图
下表列出了所有硬件组件:
部件 |
说明 |
数量 |
链接方式 |
ACC-01-6005 |
带 8GB TX2 模块的 Quartet 载板 |
1 |
https://www.flir.com/products/quartet-embedded-solution-for-tx2/ |
BFS-U3-16S2C-BD2 |
160 万像素,226 FPS,Sony IMX273,彩色 |
2 |
|
ACC-01-5009 |
用于 BFS 彩色板级相机的 S 接口和红外滤光片 |
2 |
|
BW3M60B-1000 |
6 mm S 接口镜头 |
|
http://www.boowon.co.kr/site/ |
ACC-01-2401 |
用于板级 Blackfly S 的 15 cm FPC 线缆 |
2 |
https://www.flir.com/products/15-cm-fpc-cable-for-board-level-blackfly-s/ |
XHG302 |
NVIDIA® Jetson™ TX2/TX2 4GB/TX2i 主动式散热器 |
1 |
https://connecttech.com/product/nvidia-jetson-tx2-tx1-active-heat-sink/ |
同步电缆(自制) |
1 |
||
安装杆(自制) |
1 |
应调整两个镜头,以将相机聚焦在您的应用所需的距离范围内。拧紧每个镜头上的螺钉(图 4 中以红色圈出)以保持对焦。
图 4:显示镜头螺钉的立体声系统侧视图
软件要求
a. Spinnaker
Teledyne FLIR Spinnaker SDK 已预装在适用于 TX2 的 Quartet 嵌入式解决方案中。Spinnaker 需要与相机进行通信。
b. 支持 CUDA 的 OpenCV 4.5.2
SGM(我们正在使用的立体匹配算法)需要 OpenCV 4.5.1 或更高版本。下载包含本文代码的 zip 文件,并将其解压缩到 StereoDepth 文件夹。安装 OpenCV 的脚本是 OpenCVInstaller.sh。在终端中键入以下命令:
- cd ~/StereoDepth
- chmod +x OpenCVInstaller.sh
- ./OpenCVInstaller.sh
安装程序将要求您输入管理员密码。安装程序将开始安装 OpenCV 4.5.2。下载和构建 OpenCV 可能需要几个小时。
c. Jetson-inference(如果需要深度学习)
Jetson-inference 是 NVIDIA 的开源库,可用于 Jetson 设备(如 TX2)上的 GPU 加速深度学习。此库采用 TensorRT SDK,便于在 NVIDIA GPU 进行高性能推理。Jetson-inference 为用户提供各类预训练和现成的深度学习模型,以及通过 TensorRT 部署模型的代码。若要安装 jetson-inference,请在终端输入以下命令:
- cd ~/StereoDepth
- chmod +x InferenceInstaller.sh
- ./InferenceInstaller.sh
校准
抓取和校准立体图像的代码可在 “Calibration” 文件夹中找到。使用 SpinView GUI 识别左右相机的序列号。在我们的设置中,右相机是主相机,左相机是从相机。将主从相机序列号复制到文件 grabStereoImages.cpp 第 60 和 61 行。在终端中使用以下命令构建可执行文件:
- cd ~/StereoDepth/Calibration
- mkdir build
- mkdir -p images/{left, right}
- cd build
- cmake ..
- make
从此链接打印出棋盘状图案,并将其贴在平面上用作校准目标。为了在校准时获得良好效果,在 SpinView 中将 Exposure Auto 设置为 Off 并调整曝光,使棋盘状图案清晰且白色方块不会过度曝光,如图 5 所示。收集校准图像后,增益和曝光可在 SpinView 中设置为自动。
图 5:SpinView GUI 设置
要开始收集图像,请键入
- ./grabStereoImages
代码应以大约 1 帧/秒的速度开始收集图像。左侧图像存储在 images/left 文件夹中,右侧图像存储在 images/right 文件夹中。移动目标,使其出现在图像的每个角落。您可以旋转目标,从近处和远处拍摄图像。默认情况下,该程序捕获 100 个图像对,但可以使用命令行参数进行更改:
- ./grabStereoImages 20
这将仅收集 20 对图像。请注意,这将覆盖之前写入文件夹中的所有图像。部分示例校准图像如图 6 所示。
图 6:示例校准图像
收集图像后,通过键入以下内容运行校准 Python 代码:
- cd ~/StereoDepth/Calibration
- python cameraCalibration.py
这将生成 2 个名为 “intrinsics.yml” 和 “extrinsics.yml” 的文件,其中包含立体声系统的内部和外部参数。该代码默认采用 30mm 棋盘方格,但可以根据需要进行编辑。在校准结束时,它会显示 RMS 误差,表明校准的好坏。良好校准的典型 RMS 误差应低于 0.5 像素。
实时深度图
实时计算视差的代码位于 “Depth” 文件夹中。将相机序列号复制到文件 live_disparity.cpp 第 230 和 231 行。在终端中使用以下命令构建可执行文件:
- cd ~/StereoDepth/Depth
- mkdir build
- cd build
- cmake ..
- make
将校准步骤中获得的 “intrinsics.yml” 和 “extrinsics.yml” 文件复制到此文件夹。要运行实时深度图演示,请键入
- ./live_disparity
它将显示左相机图像(原始未纠正图像)和深度图(我们的最终输出)。部分示例输出如图 7 所示。与相机的距离根据深度图右侧的图例进行颜色编码。深度图中的黑色区域意味着在该区域中没有发现视差数据。得益于 NVIDIA Jetson TX2 GPU,它在 1440 × 1080 的分辨率下可运行高达 5 帧/秒,在 720 × 540 的分辨率下可运行高达 13 帧/秒。
要查看特定点的深度,请在深度图中单击该点,深度将会显示出来,如图 7 中最后一个示例所示。
图 7:对左相机图像和相应的深度图进行采样。底部深度图还会显示特定点的深度。
人物检测
我们使用 Jetson-inference 的 DetectNet 检测图像帧中的人物。DetectNet 自带对象检测的深度学习模型架构选项。我们采用 MobileNetV2 主干网的单阶检测 (SSD) 架构优化速度和准确性。首次运行演示时,TensorRT 会创建一个序列化引擎进一步优化推理速度,只需几分钟就能完成。此引擎自动保存在文件中,以便后续运行。这里使用的架构非常高效,运行检测模块可以达到 ~50 fps。人物检测功能和实时立体深度的代码位于“DepthAndDetection”文件夹。将摄像机的序列号复制到 live_disparity.cpp 文件的第 271 和 272 行。在终端中输入以下命令,构建可执行文件:
- cd ~/StereoDepth/DepthAndDetection
mkdir
buildcd
buildcmake ..
make
将校准步骤获得的“intrinsics.yml”和“extrinsics.yml”文件复制到该文件夹。如需运行实时深度图演示,请输入
- ./live_disparity
此时会显示左侧校正彩色图像和深度图两个窗口。深度图进行了颜色编码,更利于可视化。两个窗口里的人物均被边界框框住,还显示人与摄像机的平均距离。立体处理和深度学习推理下,该演示在 1440 × 1080 分辨率下运行速度约 4 fps,在 720 × 540 分辨率下运行速度最高达 11.5 fps。
图 8:左侧摄像机图像和对应深度图的示例所有图像都显示检测到的人物以及人与摄像机的距离
即使在遮挡等复杂环境,人物检测算法也能够检测多个人员。代码会计算图像中所有人的距离,如下图所示。
图 9:左侧图像和深度图显示了多名检测到的人物及其到摄像机相应距离。
摘要
使用立体视觉来形成深度信息感知的优势众多,包括在户外工作良好,能够提供高分辨率的深度图,可通过低成本的现成组件制作。当您需要开发一个定制化的嵌入式立体感知系统,根据此处提供的说明进行操作,也将是一个相对简单的任务。