Configuring Stereo Depth
- 1. Stereo Depth Basics
- 2. Fixing noisy depth
- 3. Improving depth accuracy
- 4. Short range stereo depth
- 5. Long range stereo depth
- 6. Fixing noisy pointcloud
1. Stereo Depth Basics

Depth from disparity
depth_cm- depth in centimetersfx_px- focal length in pixelsbaseline_cm- distance between two cameras of the stereo camera pairdisparity_px- disparity in pixels
Focal Length
Disparity
Full chart hereNote the value of depth data is stored in uint16, where 0 means that the distance is invalid/unknown.How baseline distance and focal length affect depth
Wider FOV will result in worse depth accuracy, even at shorter ranges (where accuracy drop isn't as noticeable).
2. Fixing noisy depth
Scene Texture
The technique that we use is called ASV (Conventional Active Stereo Vision) as stereo matching is performed on the device the same way as on a passive stereo OAK-D.Stereo depth confidence threshold
0..255 by the stereo matching algorithm. This confidence score is kind of inverted (if, say, comparing with NN confidences):- 0 - maximum confidence that it holds a valid value
- 255 - minimum confidence, so there is more chance that the value is incorrect
Python
C++
Stereo camera pair noise
Stereo postprocessing filters
If the pipeline complains about shave/memory allocation, try increasing the HW resources used in postprocessing with
setPostProcessingHardwareResources(n_shaves, n_cmx) --> stereoDepth.setPostProcessingHardwareResources(3, 3).Median filter
Speckle filter
Temporal filter
Spatial filter
Brightness filter
Direct light source (ceiling light) - depth pixels are invalid
It also helps with rectification "artifacts", especially when you have Wide FOV lenses and you apply alpha param. When there's no available pixel, StereoDepth node will set that area to 0 (black) by default, but can be changed with stereoDepth.setRectifyEdgeFillColor(int8). This black area can then be invalidated with brightness filter, as seen below:Invalidating depth where we have rectification 'artifacts'

Threshold filter
Decimation filter
Filtering order
Python
1config.postProcessing.filteringOrder = [
2 dai.RawStereoDepthConfig.PostProcessing.Filter.TEMPORAL,
3 dai.RawStereoDepthConfig.PostProcessing.Filter.SPECKLE,
4 dai.RawStereoDepthConfig.PostProcessing.Filter.SPATIAL,
5 dai.RawStereoDepthConfig.PostProcessing.Filter.MEDIAN,
6 dai.RawStereoDepthConfig.PostProcessing.Filter.DECIMATION
7]3. Improving depth accuracy
- (mentioned above) Fixing noisy depth - depth should be high quality in order to be accurate
- (mentioned above) Stereo depth confidence threshold should be low(er) in order to get the best accuracy
- Move the camera closer to the object for the best depth accuracy
- Enable Stereo Subpixel mode, especially if the object/scene isn't close to MinZ of the camera
Move the camera closer to the object
Depth accuracy decreases exponentially with the distance from the camera. Note that with Stereo Subpixel mode enabled you can have better depth accuracy (even at a longer distance) but it only works to some extent.So to conclude, object/scene you are measuring should be as close as possible to MinZ (minimal depth perception) of the camera for best depth accuracy. You can find MinZ specification for each device in the Hardware documentation.Stereo Subpixel mode
The stereo depth pipeline is very complex (see Internal block diagram of StereoDepth node), and we will simplify it here for better understanding. It actually doesn't use confidence (eg.
stereoDepth.confidenceMap output), but cost dump, which is what is used to calculate confidence values.stereoDepth.debugDispCostDump output, just note it's a very large output (eg. 1280*800*96 => 98MB for each frame).
Stereo Subpixel mode will calculate subpixel disparity by looking at the confidence values of the 2 neighboring disparity pixels in each direction. In the above example graph, in normal mode, StereoDepth would just get the max disparity = 34 pixels, but in Subpixel mode, it will return a bit more, eg. 34.375 pixels, as confidences for pixels 35 and 36 are quite high as well.TL;DR: Stereo Subpixel mode should always provide more accurate depth, but will consume additional HW resources (see Stereo depth FPS for impact).Stereo subpixel effect on layering
This layering can especially be seen at longer distances, where these layers are exponentially further apart.But with Stereo Subpixel mode enabled, there are many more unique values possible, which produces more granular depth steps, and thus smoother a pointcloud.| Subpixel Fractional Bits | Number of Unique Values |
|---|---|
| 3 | 754 |
| 4 | 1506 |
| 5 | 3010 |
stereoDepth.setSubpixelFractionalBits(int) parameter to 3, 4 or 5 bits.4. Short range stereo depth
How to get lower MinZ
- Lowering resolution
- Enabling Stereo Extended Disparity mode
- Enabling Stereo companding mode
- Using Disparity shift - suggested in a controlled environment, where MaxZ is known
Lowering resolution to decrease MinZ
Stereo Extended Disparity mode
Stereo companding mode
- First 48 pixels it does pixel by pixel matching, meaning at longer range there's no downside
- Next 32 pixels it does matching every 2nd pixel, so accuracy is halved (at closer range)
- Last 16 pixel it does matching every 4th pixel, so accuracy is quartered (at closest range). Because accuracy is the best at closest range anyways, this is can be a good tradeoff.
Companding - effect on accuracy (75mm baseline, 800P, Normal FOV)
Google Sheets here for the above graph. Note that this graph is for full-pixel disparity, when enabling subpixel mode the accuracy will be better (see Stereo depth accuracy docs).Python
1stereo = pipeline.create(dai.node.StereoDepth)
2cfg = stereo.initialConfig.get()
3# Enable companding mode
4cfg.costMatching.enableCompanding = True
5stereo.initialConfig.set(cfg)Disparity shift
The Left graph shows min and max disparity and depth for OAK-D (7.5cm baseline, 800P resolution, ~70° HFOV) by default (disparity shift=0). See Depth from disparity. Since hardware (stereo block) has a fixed 95 pixel disparity search, DepthAI will search from 0 pixels (depth=INF) to 95 pixels (depth=71cm).Limitations: The Right graph shows the same, but at disparity shift set to 30 pixels. This means that disparity search will be from 30 pixels (depth=2.2m) to 125 pixels (depth=50cm). This also means that depth will be very accurate at the short range (theoretically below 5mm depth error).- Because of the inverse relationship between disparity and depth, MaxZ will decrease much faster than MinZ as the disparity shift is increased. Therefore, it is advised not to use a larger-than-necessary disparity shift.
- The tradeoff in reducing the MinZ this way is that objects at distances farther away than MaxZ will not be seen.
- Because of the point above, we only recommend using disparity shift when MaxZ is known, such as having a depth camera mounted above a table pointing down at the table surface.
- Output disparity map is not expanded, only the depth map. So if disparity shift is set to 50, and disparity value obtained is 90, the real disparity is 140.
- (+) Is faster, as it doesn't require an extra computation, which means there's also no extra latency
- (-) Reduces the MaxZ (significantly), while extended disparity only reduces MinZ.
method
depthai.StereoDepthConfig.setDisparityShift
Close range depth limitations
Meaning of variables on the picture:BL [cm]- Baseline of stereo cameras.Dv [cm]- Minimum distance where both cameras see an object (thus where depth can be calculated).W [pixels]- Width of mono in pixels camera or amount of horizontal pixels, also noted asHPixelsin other formulas.D [cm]- Distance from the camera plane to an object (see image here).
5. Long range stereo depth
- Narrow FOV lenses
- Wide baseline distance between stereo cameras
6. Fixing noisy pointcloud
- (mentioned above) Start with the Fixing noisy depth chapter, as otherwise, noise will produce points all over the pointcloud
- (mentioned above) Continue with the Improving depth accuracy chapter - depth inaccuracy will be easily visible in pointcloud
- Enable Stereo subpixel mode, especially due to the Stereo subpixel effect on layering
- Decimation filter for pointcloud for faster processing (FPS) and additional filtering
- Invalidating pixels around the corner should help to reduce noise around the corners of the depth frame
- Host-side pointcloud filtering for additional filtering