此页面由 AI 自动翻译。查看英文原版

本页目录

  • 如何放置
  • 输入和输出
  • DepthAI v3 ToF 架构
  • ToF 相机上的设置差异
  • ToF 设置
  • 快速调优指南:深度图像滤波器
  • 步骤 1:空白状态
  • 步骤 2:时间滤波器(从这里开始)
  • 步骤 3:斑点滤波器
  • 步骤 4:空间滤波器
  • 步骤 5:中值滤波器
  • 调整快速参考
  • ToF 运动模糊
  • 最大距离
  • ToF FPS
  • 用法
  • 示例
  • 参考

ToF

Supported on:RVC2
ToF 节点将原始的飞行时间传感器数据转换为深度信息,并同时提供基础输出和滤波后的输出。它适用于集成有 ToF 传感器的设备,例如:ToF 深度信息可以直接与空间节点一起使用,例如 SpatialDetectionNetworkSpatialLocationCalculator有关与立体视觉深度质量的比较,请参阅 ToF 深度精度

如何放置

Python

Python
1pipeline = dai.Pipeline()
2tof = pipeline.create(dai.node.ToF)

C++

C++
1dai::Pipeline pipeline;
2auto tof = pipeline.create<dai::node::ToF>();

输入和输出

DepthAI v3 ToF 架构

DepthAI v3 ToF 管道最好理解为两个层:
  1. ToF 基础解码 将传感器测量值转换为基础信号(rawDepthamplitudeintensityphase)并处理相位解卷等 ToF 特定解码设置。
  2. 滤波阶段 使用面向 ToF 的滤波预设和运行时滤波器配置生成滤波后的深度输出(depth)。
RVC2 上,滤波阶段是在主机上运行的。

ToF 相机上的设置差异

许多 OAK 深度示例都假定采用经典的立体视觉布局(一个彩色摄像头 + CAM_* 插槽上的单色立体视觉对)。 ToF 相机通常用作 ToF + 彩色摄像头 的设置(两个功能摄像头源),其中深度信息来自 dai.node.ToF,而不是来自 StereoDepth通用应用程序中常见的集成陷阱:
  • 不要将 ToF 传感器视为普通的彩色预览源。
  • 不要为仅 ToF 的设备自动创建默认的单色立体视觉流。
  • ToF 构建深度,仅在需要时(例如,用于对齐/叠加)添加彩色流。

ToF 设置

常见的基准解码设置(来自 ToFConfig):
  • 光学校正:将径向距离转换为深度(Z 图),以便其行为与立体视觉深度使用方式相匹配。
  • 去畸变depthamplitude 默认进行去畸变。
  • 相位解卷:以增加噪声为代价来扩展测量范围。
  • 相位抖动时间滤波器:通过组合抖动/非抖动捕获来减少噪声。
  • 突发模式:避免解码中的帧重用,通过牺牲输出速率来减少运动伪影。
通过解卷级别的大致范围:
  • 0(禁用):高达约 1.87 m(80 MHz)
  • 1:高达约 3.0 m
  • 2:高达约 4.5 m
  • 3:高达约 6.0 m
  • 4:高达约 7.5 m
后处理通过 ImageFiltersImageFiltersConfig 进行配置。有关基于置信度的清理,请参阅 ToFDepthConfidenceFilterConfig

快速调优指南:深度图像滤波器

调优目标是在干净、无噪声的深度图与移动对象的快速、准确更新之间取得平衡。 对于 ToF 深度输出,delta 通常以深度单位(通常是毫米)解释,而 alpha[0.0, 1.0] 范围内的混合因子。 将以下所有值视为起点,并根据您的场景进行调整。

步骤 1:空白状态

在调整之前,禁用所有滤波器。 这有助于您测量基线噪声、验证传感器放置/照明,并避免通过软件滤波来掩盖设置问题。

步骤 2:时间滤波器(从这里开始)

首先调整 TemporalFilterParams,因为它控制随时间变化的动态平滑。
  • delta:用于判断深度变化是显著噪声还是正常变化的阈值。
    • delta = 15 开始。
    • 对于较大的物体(例如约 50 毫米的物体高度),使用 delta = 25 以便运动快速更新。
    • 对于小型物体,将其收紧至 delta = 10
  • alpha:当前帧与历史帧的混合权重。
    • 较低的 alpha(例如 0.1)会产生更平滑的输出,但可能引入延迟/拖尾。
    • 较高的 alpha(例如 0.4)更新速度更快,但平滑效果较差。
  • 重要提示delta = 0 会使几乎所有变化都变得显著,并很大程度上绕过时间混合。

步骤 3:斑点滤波器

使用 SpeckleFilterParams 来去除单帧中的孤立斑块和类似椒盐噪声的伪影。
  • differenceThreshold(boss 别名:max_diff):用于将相邻像素分组到同一区域的阈值。
  • speckleRange(boss 别名:max_speckle_size):要去除的最大区域大小。
  • 调整策略:逐渐增加 speckleRange 以去除较大的浮动斑块,但要避免删除真实小型对象的数值。

步骤 4:空间滤波器

使用 SpatialFilterParams 在保留边缘的同时平滑对象表面。
  • alpha:平滑强度(较低的值通常平滑效果更好)。
  • delta:边缘保持阈值;较大的深度跳变被视为边缘,不会被混合。
  • holeFillingRadius:使用周围的有效数据填充无效(0)像素。
  • numIterations:更多次的迭代可以以轻微的处理成本优化输出。

步骤 5:中值滤波器

当存在残留的椒盐噪声时,使用 MedianFilterParams 进行最终的激进清理。
  • 此节点中支持的模式:MEDIAN_OFFKERNEL_3x3KERNEL_5x5
  • 使用最小的内核来解决噪声问题,以最大程度地减少边缘/细节损失。

调整快速参考

滤波器关键参数主要用例权衡
时间delta, alpha平滑随时间变化的噪声平滑度 vs 运动延迟
斑点speckleRange, differenceThreshold去除孤立斑块/噪声清洁度 vs 删除小型对象
空间delta, alpha, holeFillingRadius, numIterations边缘保持的表面平滑平滑度 vs 处理成本
中值KERNEL_3x3, KERNEL_5x5激进的椒盐噪声清理噪声去除 vs 边缘/细节模糊
有关完整的参数定义和运行时配置流程,请参阅 ImageFiltersImageFiltersConfigToFDepthConfidenceFilterConfig

ToF 运动模糊

要减少运动模糊:
  • 增加传感器 FPS(最高可达 160 FPS),同时考虑更高的系统负载和缩短的曝光时间。
  • 禁用相位抖动时间滤波器(噪声更大)。
  • 禁用相位解缠(降低最大范围)。
  • 在适用时启用突发模式。

最大距离

最大距离取决于调制频率和相位解缠设置。
Math
1c = 299792458.0 # 光速,单位 m/s
2
3MAX_80MHZ_M = c / (80000000 * 2) = 1.873 m
4MAX_100MHZ_M = c / (100000000 * 2) = 1.498 m
5
6MAX_DIST_80MHZ_M = (phaseUnwrappingLevel + 1) * 1.873 + (phaseUnwrapErrorThreshold / 2)
7MAX_DIST_100MHZ_M = (phaseUnwrappingLevel + 1) * 1.498 + (phaseUnwrapErrorThreshold / 2)

ToF FPS

传感器/发射器最高可运行 160 FPS。有效的深度输出取决于解码/滤波器设置(例如突发模式和相位处理)。

用法

Python

Python
1pipeline = dai.Pipeline()
2
3socket = dai.CameraBoardSocket.AUTO
4preset = dai.ImageFiltersPresetMode.TOF_MID_RANGE
5tof = pipeline.create(dai.node.ToF).build(socket, preset)
6
7# 基础和滤波后的输出
8raw_depth_q = tof.rawDepth.createOutputQueue()
9depth_q = tof.depth.createOutputQueue()
10
11# 运行时配置队列(在所选 API 绑定中可用)
12base_cfg_q = tof.tofBaseInputConfig.createInputQueue()
13filters_cfg_q = tof.imageFiltersInputConfig.createInputQueue()

C++

C++
1dai::Pipeline pipeline;
2
3auto tof = pipeline.create<dai::node::ToF>()->build(
4    dai::CameraBoardSocket::AUTO,
5    dai::ImageFiltersPresetMode::TOF_MID_RANGE
6);
7
8auto rawDepthQ = tof->rawDepth.createOutputQueue();
9auto depthQ = tof->depth.createOutputQueue();

示例

参考

class

dai::node::ToF

variable
Subnode< ToFBase > tofBase
variable
Subnode< ImageFilters > imageFilters
variable
Output & rawDepth
Raw depth output from ToF sensor
variable
Output & depth
Filtered depth output
variable
Output & amplitude
Amplitude output
variable
Output & intensity
Intensity output
variable
Output & phase
Phase output
variable
Input & tofBaseInputConfig
Input config for ToF base node
variable
Input & imageFiltersInputConfig
Input config for image filters
variable
ToFBase & tofBaseNode
ToF base node
variable
ImageFilters & imageFiltersNode
Image filters node
inline function
ToF(const std::shared_ptr< Device > & device)
function
~ToF()
inline function
void buildInternal()
inline function
std::shared_ptr< ToF > build(dai::CameraBoardSocket boardSocket, dai::ImageFiltersPresetMode presetMode, std::optional< float > fps)

需要帮助?

请前往 Discussion Forum 获取技术支持或提出您可能有的任何其他问题。