DepthAI v2 has been superseded by DepthAI v3. You are viewing legacy documentation.

本页目录

  • 如何放置
  • 输入和输出
  • StereoDepth 节点内部框图
  • 当前可配置模块
  • 局限性
  • 运行时更改相机标定
  • 深度预设
  • 深度预设
  • 立体深度帧率
  • 使用方法
  • 功能示例
  • 参考
  • 视差
  • 利用视差图计算深度
  • 最小立体深度距离
  • 视差偏移以降低最小深度感知
  • 最大立体深度距离
  • 深度感知精度
  • 局限性
  • 测量真实世界物体尺寸

StereoDepth

StereoDepth 节点计算立体相机对(2x MonoCamera/ColorCamera)的视差和/或深度。 建议按照配置立体深度教程以获得最佳深度结果。

如何放置

Python

Python
1pipeline = dai.Pipeline()
2stereo = pipeline.create(dai.node.StereoDepth)

C++

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

输入和输出

还有调试输出(均为 ImgFrame):debugDispLrCheckIt1debugDispLrCheckIt2debugExtDispLrCheckIt1debugExtDispLrCheckIt2debugDispCostDump置信度图

StereoDepth 节点内部框图

软件/depthai/节点//depth_diagram.webp
图中红色矩形表示可通过 API 配置的固件设置。灰色矩形表示尚未暴露给 API 的设置。我们计划尽可能多地暴露可配置项,但如果您希望这些设置更早可用,请告知我们。点击图片将跳转到 Web 应用。部分方块附有注释,提供更多技术信息。

当前可配置模块

  • 立体模式
    • 左右校验
      • 左右校验(LR-Check)用于移除因物体边界遮挡(左右相机视图略有不同)导致的错误视差像素。
        1. 通过 R->L 方向匹配计算视差。
        2. 通过 L->R 方向匹配计算视差。
        3. 结合步骤 1 和 2 的结果,在 Shave 上运行:每个像素 d = disparity_LR(x,y) 与 disparity_RL(x-d,y) 比较。如果差值超过阈值,则最终视差图中 (x,y) 处的像素失效。
      • 您可以使用 debugDispLrCheckIt1debugDispLrCheckIt2 调试输出进行调试/微调。
    • 扩展视差
      • 扩展视差模式允许检测给定基线下的更近距离物体。这会将最大视差搜索范围从 96 增加到 191,即范围为 [0..190]。
        1. 在原始尺寸图像(例如 1280x720)上计算视差。
        2. 在 2 倍下采样图像(例如 640x360)上计算视差。
        3. 在 Shave 上结合两级视差,有效覆盖总计 191 像素的视差范围(相对于原始分辨率)。
      • 您可以使用 debugExtDispLrCheckIt1debugExtDispLrCheckIt2 调试输出进行调试/微调。
    • 亚像素视差
      • 亚像素模式提高了精度,在远距离测量中尤其有用。它还有助于更好地估计表面法线。
      • 在此模式下,立体相机执行:94 个深度步长 * 8 个亚像素深度步长 + 2(最小/最大值)= 754 个深度步长。
      • 如需比较正常视差与亚像素视差图像,请单击此处
  • 深度滤波器
    • 深度滤波 / 深度后处理 在深度管线的末尾执行,有助于降噪并提升整体深度质量。
  • 网格文件
    • 网格文件(单应性矩阵)通过相机内参、畸变系数和矫正旋转矩阵生成。这些文件有助于克服相机畸变,提高准确性,并在使用广角镜头时发挥作用。
    • 目前,网格文件仅在标定过程中在主机上为立体相机生成。生成的网格文件存储在 depthai/resources 中,用户可以将其加载到设备上。这一过程将在未来的版本中迁移至设备端完成。
  • 置信度阈值
    • 置信度阈值:立体深度算法在右摄像头图像中搜索与左图像匹配的特征(沿 96 个视差级别)。过程中,它会计算每个视差级别的代价,并选择两个视差之间的最小代价,进而计算每个像素的置信度。仅当深度置信度低于置信度阈值时,Stereo 节点才会输出视差/深度像素(置信度值越低,深度精度越高)。
    • LR 检查阈值:当 LR 和 RL 视差之间的差异小于 LR 检查阈值时,视差才会被纳入输出。

局限性

  • 当子像素模式设置为 4 或 5 位时,中值滤波禁用。
  • 要实现 RGB-深度对齐,RGB 摄像头必须与立体摄像头对处于同一水平线上。
  • 使用视差偏移时,RGB-深度对齐无法工作。

运行时更改相机标定

depthai-2.29.0 版本起,支持在运行时更改相机标定。 标定可通过 device.setCalibration() 方法更改,适用于因环境因素导致设备立体质量随时间下降的场景。 相同的数据可通过 device.getCalibration() 获取。

深度预设

我们提供了一些深度预设,以便快速为不同场景配置 StereoDepth 节点,无需手动设置 配置立体深度 中列出的所有参数。

深度预设

特性默认人脸高细节机器人
基础配置文件HIGH_DENSITYHIGH_DENSITYHIGH_ACCURACYHIGH_DENSITY
中值滤波7x7 核关闭关闭7x7 核
子像素精度3 位5 位5 位3 位
扩展视差
范围0-15 米3 厘米-3 米0-15 米0-10 米
时间滤波启用启用启用禁用
用例通用人脸跟踪、生物识别3D 扫描、物体细节导航、障碍物检测
所有预设均包含:
  • 左右一致性检查
  • 2 倍降采样(像素跳跃)
  • 斑点滤波(范围:200,阈值:2)
  • 3 个用于后处理的硬件资源

立体深度帧率

StereoDepth 在多个硬件模块上处理相当多的复杂操作,帧率取决于该节点的设置。因此,我们不妨查看每个操作的延迟,而非帧率。管线中的第一步(参见 内部框图)是 校正,在 warp 引擎上运行。由于广角帧需要更复杂的网格进行校正,处理时间稍长。
处理 \ 分辨率400P [ms]720P [ms]800P [ms]
校正1.556
广视场角校正2.589
然后是实际的 立体视差匹配,在独立的立体引擎上运行。这通常是最耗时的部分(除非使用大量后处理滤波器),因此很可能是管线中的瓶颈。首先定义以下术语:
  • LR:左右检查(stereo.setLeftRightCheck())。需要执行 2 次立体匹配操作(L→R 和 R→L 方向),然后合并结果。
  • Ext:扩展视差模式(stereo.setExtendedDisparity())。需要执行 2 次立体匹配操作(原始和降采样),然后合并结果。
  • Sub:子像素匹配(stereo.setSubpixel())。每个像素需要 96 字节的代价图(每个视差级别一个字节),因此对于 800P 帧,约 98MB 的数据需要传输到 CMX 内存(供 SHAVEs 使用)进行子像素计算。此情况下的瓶颈是内存带宽(~4.1GB/秒)。子像素位数不影响延迟。
处理过程 \ 分辨率400P [毫秒]720P [毫秒]800P [毫秒]
无LR, 无Ext, 无Sub3.47.48.1
无LR, 无Ext, Sub6.221.723.9
无LR, Ext, 无Sub8.521.523.5
无LR, Ext, Sub1132.736.7
LR, 无Ext, 无Sub7.41819.8
LR, 无Ext, Sub10.127.630.5
LR, Ext, 无Sub16.743.748.3
LR, Ext, Sub20.45662
由于这一步很可能是瓶颈,我们可以由此计算帧率。因此,如果你在800P分辨率下启用LR、Ext和Sub,将获得约**(1秒/62毫秒 =) 16 FPS**。最后是滤波环节——例如中值滤波(在中值硬件模块上运行),这是一个简单的操作,不会增加太多延迟。内核类型(3x35x57x7)不影响延迟:
处理过程 \ 分辨率400P [毫秒]720P [毫秒]800P [毫秒]
中值滤波(3x3 / 5x5 / 7x70.81.81.8
还有其他后处理滤波器,它们可能会消耗大量计算资源并增加延迟,但我们尚未对其进行详细测量。

使用方法

Python

Python
1pipeline = dai.Pipeline()
2stereo = pipeline.create(dai.node.StereoDepth)
3
4# 更好地处理遮挡:
5stereo.setLeftRightCheck(False)
6# 更近的最小深度,视差范围翻倍:
7stereo.setExtendedDisparity(False)
8# 远距离精度更高,分数视差32级:
9stereo.setSubpixel(False)
10
11# 预先定义并配置MonoCamera节点
12left.out.link(stereo.left)
13right.out.link(stereo.right)

C++

C++
1dai::Pipeline pipeline;
2auto stereo = pipeline.create<dai::node::StereoDepth>();
3
4// 更好地处理遮挡:
5stereo->setLeftRightCheck(false);
6// 更近的最小深度,视差范围翻倍:
7stereo->setExtendedDisparity(false);
8// 远距离精度更高,分数视差32级:
9stereo->setSubpixel(false);
10
11// 预先定义并配置MonoCamera节点
12left->out.link(stereo->left);
13right->out.link(stereo->right);

功能示例

参考

class

depthai.node.StereoDepth(depthai.Node)

class
PresetMode
Preset modes for stereo depth.  Members:    HIGH_ACCURACY : **Deprecated:** Will be removed in future releases and replaced with DEFAULT    HIGH_DENSITY : **Deprecated:** Will be removed in future releases and replaced with DEFAULT    DEFAULT    FACE    HIGH_DETAIL    ROBOTICS
method
enableDistortionCorrection(self, arg0: bool)
Equivalent to useHomographyRectification(!enableDistortionCorrection)
method
getMaxDisparity(self) -> float: float
Useful for normalization of the disparity map.  Returns:     Maximum disparity value that the node can return
method
loadMeshData(self, dataLeft: collections.abc.Sequence [ typing.SupportsInt ], dataRight: collections.abc.Sequence [ typing.SupportsInt ])
Specify mesh calibration data for 'left' and 'right' inputs, as vectors of bytes. Overrides useHomographyRectification behavior. See `loadMeshFiles` for the expected data format
method
loadMeshFiles(self, pathLeft: Path, pathRight: Path)
Specify local filesystem paths to the mesh calibration files for 'left' and 'right' inputs.  When a mesh calibration is set, it overrides the camera intrinsics/extrinsics matrices. Overrides useHomographyRectification behavior. Mesh format: a sequence of (y,x) points as 'float' with coordinates from the input image to be mapped in the output. The mesh can be subsampled, configured by `setMeshStep`.  With a 1280x800 resolution and the default (16,16) step, the required mesh size is:  width: 1280 / 16 + 1 = 81  height: 800 / 16 + 1 = 51
method
setAlphaScaling(self, arg0: typing.SupportsFloat)
Free scaling parameter between 0 (when all the pixels in the undistorted image are valid) and 1 (when all the source image pixels are retained in the undistorted image). On some high distortion lenses, and/or due to rectification (image rotated) invalid areas may appear even with alpha=0, in these cases alpha < 0.0 helps removing invalid areas. See getOptimalNewCameraMatrix from opencv for more details.
method
setBaseline(self, arg0: typing.SupportsFloat)
Override baseline from calibration. Used only in disparity to depth conversion. Units are centimeters.
method
setConfidenceThreshold(self, arg0: typing.SupportsInt)
Confidence threshold for disparity calculation  Parameter ``confThr``:     Confidence threshold value 0..255
method
setDefaultProfilePreset(self, arg0: StereoDepth.PresetMode)
Sets a default preset based on specified option.  Parameter ``mode``:     Stereo depth preset mode
method
method
setDepthAlignmentUseSpecTranslation(self, arg0: bool)
Use baseline information for depth alignment from specs (design data) or from calibration. Default: true
method
setDisparityToDepthUseSpecTranslation(self, arg0: bool)
Use baseline information for disparity to depth conversion from specs (design data) or from calibration. Default: true
method
setEmptyCalibration(self)
Specify that a passthrough/dummy calibration should be used, when input frames are already rectified (e.g. sourced from recordings on the host)
method
setExtendedDisparity(self, enable: bool)
Disparity range increased from 0-95 to 0-190, combined from full resolution and downscaled images.  Suitable for short range objects. Currently incompatible with sub-pixel disparity
method
setFocalLength(self, arg0: typing.SupportsFloat)
Override focal length from calibration. Used only in disparity to depth conversion. Units are pixels.
method
setFocalLengthFromCalibration(self, arg0: bool)
Whether to use focal length from calibration intrinsics or calculate based on calibration FOV. Default value is true.
method
method
setLeftRightCheck(self, enable: bool)
Computes and combines disparities in both L-R and R-L directions, and combine them.  For better occlusion handling, discarding invalid disparity values
method
setMedianFilter(self, arg0: depthai.MedianFilter)
Parameter ``median``:     Set kernel size for disparity/depth median filtering, or disable
method
setMeshStep(self, width: typing.SupportsInt, height: typing.SupportsInt)
Set the distance between mesh points. Default: (16, 16)
method
setNumFramesPool(self, arg0: typing.SupportsInt)
Specify number of frames in pool.  Parameter ``numFramesPool``:     How many frames should the pool have
method
method
setOutputKeepAspectRatio(self, keep: bool)
Specifies whether the frames resized by `setOutputSize` should preserve aspect ratio, with potential cropping when enabled. Default `true`
method
method
setOutputSize(self, width: typing.SupportsInt, height: typing.SupportsInt)
Specify disparity/depth output resolution size, implemented by scaling.  Currently only applicable when aligning to RGB camera
method
setPostProcessingHardwareResources(self, arg0: typing.SupportsInt, arg1: typing.SupportsInt)
Specify allocated hardware resources for stereo depth. Suitable only to increase post processing runtime.  Parameter ``numShaves``:     Number of shaves.  Parameter ``numMemorySlices``:     Number of memory slices.
method
setRectification(self, enable: bool)
Rectify input images or not.
method
setRectificationUseSpecTranslation(self, arg0: bool)
Obtain rectification matrices using spec translation (design data) or from calibration in calculations. Should be used only for debugging. Default: false
method
setRectifyEdgeFillColor(self, color: typing.SupportsInt)
Fill color for missing data at frame edges  Parameter ``color``:     Grayscale 0..255, or -1 to replicate pixels
method
setRectifyMirrorFrame(self, arg0: bool)
DEPRECATED function. It was removed, since rectified images are not flipped anymore. Mirror rectified frames, only when LR-check mode is disabled. Default `true`. The mirroring is required to have a normal non-mirrored disparity/depth output.  A side effect of this option is disparity alignment to the perspective of left or right input: `false`: mapped to left and mirrored, `true`: mapped to right. With LR-check enabled, this option is ignored, none of the outputs are mirrored, and disparity is mapped to right.  Parameter ``enable``:     True for normal disparity/depth, otherwise mirrored
method
setRuntimeModeSwitch(self, arg0: bool)
Enable runtime stereo mode switch, e.g. from standard to LR-check. Note: when enabled resources allocated for worst case to enable switching to any mode.
method
setSubpixel(self, enable: bool)
Computes disparity with sub-pixel interpolation (3 fractional bits by default).  Suitable for long range. Currently incompatible with extended disparity
method
setSubpixelFractionalBits(self, subpixelFractionalBits: typing.SupportsInt)
Number of fractional bits for subpixel mode. Default value: 3. Valid values: 3,4,5. Defines the number of fractional disparities: 2^x. Median filter postprocessing is supported only for 3 fractional bits.
method
useHomographyRectification(self, arg0: bool)
Use 3x3 homography matrix for stereo rectification instead of sparse mesh generated on device. Default behaviour is AUTO, for lenses with FOV over 85 degrees sparse mesh is used, otherwise 3x3 homography. If custom mesh data is provided through loadMeshData or loadMeshFiles this option is ignored.  Parameter ``useHomographyRectification``:     true: 3x3 homography matrix generated from calibration data is used for     stereo rectification, can't correct lens distortion. false: sparse mesh is     generated on-device from calibration data with mesh step specified with     setMeshStep (Default: (16, 16)), can correct lens distortion. Implementation     for generating the mesh is same as opencv's initUndistortRectifyMap     function. Only the first 8 distortion coefficients are used from calibration     data.
property
confidenceMap
Outputs ImgFrame message that carries RAW8 confidence map. Lower values means higher confidence of the calculated disparity value. RGB alignment, left-right check or any postproccessing (e.g. median filter) is not performed on confidence map.
property
debugDispCostDump
Outputs ImgFrame message that carries cost dump of disparity map. Useful for debugging/fine tuning.
property
debugDispLrCheckIt1
Outputs ImgFrame message that carries left-right check first iteration (before combining with second iteration) disparity map. Useful for debugging/fine tuning.
property
debugDispLrCheckIt2
Outputs ImgFrame message that carries left-right check second iteration (before combining with first iteration) disparity map. Useful for debugging/fine tuning.
property
debugExtDispLrCheckIt1
Outputs ImgFrame message that carries extended left-right check first iteration (downscaled frame, before combining with second iteration) disparity map. Useful for debugging/fine tuning.
property
debugExtDispLrCheckIt2
Outputs ImgFrame message that carries extended left-right check second iteration (downscaled frame, before combining with first iteration) disparity map. Useful for debugging/fine tuning.
property
depth
Outputs ImgFrame message that carries RAW16 encoded (0..65535) depth data in depth units (millimeter by default).  Non-determined / invalid depth values are set to 0
property
disparity
Outputs ImgFrame message that carries RAW8 / RAW16 encoded disparity data: RAW8 encoded (0..95) for standard mode; RAW8 encoded (0..190) for extended disparity mode; RAW16 encoded for subpixel disparity mode: - 0..760 for 3 fractional bits (by default) - 0..1520 for 4 fractional bits - 0..3040 for 5 fractional bits
property
initialConfig
Initial config to use for StereoDepth.
property
inputConfig
Input StereoDepthConfig message with ability to modify parameters in runtime. Default queue is non-blocking with size 4.
property
left
Input for left ImgFrame of left-right pair  Default queue is non-blocking with size 8
property
outConfig
Outputs StereoDepthConfig message that contains current stereo configuration.
property
rectifiedLeft
Outputs ImgFrame message that carries RAW8 encoded (grayscale) rectified frame data.
property
rectifiedRight
Outputs ImgFrame message that carries RAW8 encoded (grayscale) rectified frame data.
property
right
Input for right ImgFrame of left-right pair  Default queue is non-blocking with size 8
property
syncedLeft
Passthrough ImgFrame message from 'left' Input.
property
syncedRight
Passthrough ImgFrame message from 'right' Input.

视差

视差指的是立体对中左右图像两个对应点之间的距离。
软件/深度AI/节点/视差解释.webp
在计算视差时,立体匹配算法会为视差图中的每个像素分配一个置信度值 0..255,含义如下:
  • 0 - 最大置信度,表示值有效
  • 255 - 最小置信度,值更可能错误
(这个置信度评分是某种反转的,比如与神经网络相比)对于最终的视差图,会根据置信度阈值进行滤波:置信度分数大于阈值的像素会被无效化,即其视差值设为零。你可以通过 stereo.initialConfig.setConfidenceThreshold() 设置置信度阈值。

利用视差图计算深度

视差和深度成反比。随着视差减小,深度会根据基线和焦距呈指数增长。这意味着,如果视差值接近零,视差的微小变化会导致深度的巨大变化。同样,如果视差值较大,视差的大幅变化也不会引起深度的巨大变化。考虑到这一点,深度可以用以下公式计算:
Python
1depth = focal_length_in_pixels * baseline / disparity_in_pixels
其中 baseline 是两个单目摄像头之间的距离。注意 baseline 和 depth 的单位相同。要获取以像素为单位的焦距,可以使用校准读取器,因为像素焦距(intrinsics[0][0])写在摄像头内参中。
Python
1import depthai as dai
2
3with dai.Device() as device:
4  calibData = device.readCalibration()
5  intrinsics = calibData.getCameraIntrinsics(dai.CameraBoardSocket.CAM_C)
6  print('Right mono camera focal length in pixels:', intrinsics[0][0])
以下是焦距(以像素为单位)的理论计算:
Python
1focal_length_in_pixels = image_width_in_pixels * 0.5 / tan(HFOV * 0.5 * PI/180)
2
3# 使用400P单目相机分辨率,HFOV=71.9度
4focal_length_in_pixels = 640 * 0.5 / tan(71.9 * 0.5 * PI / 180) = 441.25
5
6# 使用800P单目相机分辨率,HFOV=71.9度
7focal_length_in_pixels = 1280 * 0.5 / tan(71.9 * 0.5 * PI / 180) = 882.5
使用OAK-D(基线为7.5cm)计算深度值的示例:
Python
1# 对于OAK-D @ 400P单目相机,视差例如50像素
2depth = 441.25 * 7.5 / 50 = 66.19 # cm
3
4# 对于OAK-D @ 800P单目相机,视差例如10像素
5depth = 882.5 * 7.5 / 10 = 661.88 # cm
注意,视差深度数据以uint16存储,其中0是一个特殊值,表示距离未知。

最小立体深度距离

如果近距离物体的深度结果看起来奇怪,很可能是因为它们低于设备的最小深度感知距离。要计算这个最小距离,使用使用视差图计算深度,并选择 disparity_in_pixels 参数的最大值(注意它是反比关系,因此最大值会产生最小的结果)。例如,OAK-D的基线为7.5cm, focal_length_in_pixels 为882.5像素, disparity_in_pixels 的默认最大值为95。通过使用使用视差图计算深度,我们得到:
Python
1min_distance = focal_length_in_pixels * baseline / disparity_in_pixels = 882.5 * 7.5cm / 95 = 69.67cm
或大约70cm。然而,通过以下选项,这个距离可以减少一半(对于OAK-D约为35cm):
  1. 将分辨率改为640x400,而不是标准的1280x800。
  2. 启用扩展视差。
扩展视差模式将视差级别从标准的96像素增加到191,从而使最小深度减半。它通过在原始1280x720图像和缩小后的640x360图像上计算96像素视差,然后将它们合并为191级视差来实现。更多信息请参见当前可配置模块中的扩展视差标签。使用之前的OAK-D示例,disparity_in_pixels 现在变为190,最小距离为:
Python
1min_distance = focal_length_in_pixels * baseline / disparity_in_pixels = 882.5 * 7.5cm / 190 = 34.84cm
或大约35cm。请参阅这些示例,了解如何启用扩展视差。

视差偏移以降低最小深度感知

另一种感知更近距离范围的方法是使用视差偏移。视差偏移将偏移视差搜索的起点,这将显著降低最大深度(MazZ)感知,但也会降低最小深度(MinZ)感知。视差偏移可以与扩展/亚像素/左右检查模式结合使用。
https://user-images.githubusercontent.com/18037362/189375017-2fa137d2-ad6b-46de-8899-6304bbc6c9d7.png
左图显示了默认情况下(视差偏移=0)OAK-D(基线7.5cm,800P分辨率,~70° HFOV)的最小和最大视差及深度。参见使用视差图计算深度。由于硬件(立体模块)具有固定的95像素视差搜索,DepthAI将搜索从0像素(深度=无穷远)到95像素(深度=71cm)。右图显示了相同情况,但视差偏移设置为30像素。这意味着视差搜索将从30像素(深度=2.2m)到125像素(深度=50cm)。这也意味着深度在短距离内将非常准确(理论上深度误差低于5mm)。限制
  • 由于视差与深度之间的反比关系,随着视差偏移的增加,MaxZ的减小速度将远快于MinZ。因此,建议不要使用超过必要的视差偏移
  • 以这种方式减少MinZ的代价是,距离大于MaxZ的物体将无法被看到
  • 由于上述原因,我们仅建议在已知MaxZ的情况下使用视差偏移,例如将深度摄像头安装在桌子上方并指向桌面。
  • 输出的视差图不会扩展,只有深度图会扩展。因此,如果视差偏移设置为50,获取的视差值为90,则实际视差为140。
与扩展视差相比,视差偏移:
  • (+) 速度更快,因为它不需要额外的计算,这意味着没有额外的延迟
  • (-) 会显著降低最大Z值 (MaxZ),而扩展视差只会降低最小Z值 (MinZ)。
视差偏移可以与扩展视差结合使用。
method

depthai.StereoDepthConfig.setDisparityShift

最大立体深度距离

最大深度感知距离取决于(深度感知精度)。计算此距离的公式是近似值,如下所示:
Python
1Dm = (baseline/2) * tan((90 - HFOV / HPixels)*pi/180)
因此,使用此公式计算现有型号的理论最大距离为:
Python
1# 对于 OAK-D(7.5厘米基线)
2Dm = (7.5/2) * tan((90 - 71.9/1280)*pi/180) = 3825.03厘米 = 38.253
4# 对于 OAK-D-CM4(9厘米基线)
5Dm = (9/2) * tan((90 - 71.9/1280)*pi/180) = 4590.04厘米 = 45.9
如果需要对远距离测量进行更高精度的测量,请考虑启用亚像素视差或使用更大的单色相机基线距离。对于自定义基线,您可以考虑使用 OAK-FFC 设备或设计自己的基板 PCB 以实现所需的基线。更多信息请参见“立体模式”选项卡下的“亚像素视差”,位于 当前可配置模块

深度感知精度

视差深度通过将一张图像中的特征与另一张图像进行匹配来工作,其精度基于多个参数:物体/背景的纹理背景可能会干扰物体检测,因为背景本身也是物体,这会使深度感知精度降低。因此,视差深度在室外环境中效果非常好,因为那里极少有完全干净的空白表面——但在室内环境中(至少在干净的建筑物中)相对常见。光照如果光照不足,视差图的置信度会很低,从而导致深度图噪声较大。基线/到物体的距离较短的基线使我们能够在较近的距离检测深度,前提是物体在两个帧中都可见。然而,由于表示物体的像素较少,且视差向0衰减得更快,这会降低远距离的精度。 因此,通常的规范是根据我们希望检测物体的远近调整基线。

局限性

由于深度是根据视差计算的,而视差需要像素重叠,因此在左侧单色相机的左侧和右侧单色相机的右侧,固有地存在一个垂直条带,其中深度无法计算,因为该区域仅被一个相机看到。该条带在下图中标记为 B
https://user-images.githubusercontent.com/59799831/135310921-67726c28-07e7-4ffa-bc8d-74861049517e.png
图中变量的含义:
  • BL [cm] - 立体相机的基线。
  • Dv [cm] - 两个相机都能看到物体的最小距离(即可以计算深度的距离)。
  • B [pixels] - 无法计算深度的条带宽度。
  • W [pixels] - 单色相机的像素宽度或水平像素数,在其他公式中也记作 HPixels
  • D [cm] - 从相机平面到物体的距离(参见图像 测量真实世界物体尺寸)。
  • F [cm] - 在距离 D 处图像的宽度。
https://user-images.githubusercontent.com/59799831/135310972-c37ba40b-20ad-4967-92a7-c71078bcef99.png
通过使用 tan 函数,可以得到以下公式:
  • F = 2 * D * tan(HFOV/2)
  • Dv = (BL/2) * tan(90 - HFOV/2)
为了得到 B,我们可以再次使用 tan 函数(与 F 相同),但这次 还必须乘以 WF 的比值,以便将单位转换为像素。 由此得到以下公式:
Python
1B = 2 * Dv * tan(HFOV/2) * W / F
2B = 2 * Dv * tan(HFOV/2) * W / (2 * D * tan(HFOV/2))
3B = W * Dv / D  # 像素
例如:如果我们使用 OAK-D,其 HFOV 为 72°,基线 (BL) 为 7.5 厘米,并且使用 640x400 (400P) 分辨率,因此 W = 640,物体距离 D = 100 厘米,我们可以 按以下方式计算 B
Command Line
1Dv = 7.5 / 2 * tan(90 - 72/2) = 3.75 * tan(54°) = 5.16 cm
2B = 640 * 5.16 / 100 = 33 # 像素
Credit for calculations and images goes to our community member gregflurry, which he made on 这个 论坛帖子。

测量真实世界物体尺寸

由于深度图包含Z距离,与相机平行的物体可以精确测量。对于不平行的物体,可以使用欧几里得距离计算。请参考下图:
software/depthai/nodes//Euclidian_distance_fig.webp
当运行例如 RGB & MobilenetSSD with spatial data 示例时,你可以使用下面的代码(在示例代码第143行之后)从 XYZ 坐标(SpatialImgDetections)计算检测到物体的距离:
Python
1distance = math.sqrt(detection.spatialCoordinates.x ** 2 + detection.spatialCoordinates.y ** 2 + detection.spatialCoordinates.z ** 2) # mm

需要帮助?

请前往 OAKChina 官网 获取技术支持或解答您的任何疑问。