You aim a stereo depth camera at a scene that does not move, and single pixels swing by tens of centimetres between frames — up to 80 cm in the case this guide works through. The initialization is not the problem: opening a 640 × 480 z16 depth stream at 30 fps is a correct way to start this class of active IR stereo camera, and no precision parameter hides in that format tuple. The scatter is the sensing method working as designed. Stereo depth comes from a division, and the uncertainty of that division grows with the square of range and with how little texture the surface offers the matcher. Here are the formula, a worked example that reproduces an 80 cm jump from real numbers, the causes ranked by probability with a test for each, and the fixes in the order that pays off.
The transport is fine — the matcher is what moves
The z16 range stream stores millimetre-scale steps, orders of magnitude finer than the 80 cm you are chasing, so neither the format nor the metric conversion sets your limit — the conversion is covered in 16-bit range images to millimetres. What the camera measures is disparity: the sideways shift of a surface feature between the left and right images. Depth is then computed per pixel, by the arithmetic in depth from a matched stereo point pair. When the matcher changes its mind by a few pixels between frames — which weak texture makes it do — the computed depth lands somewhere else. At short range that somewhere is millimetres away; at mid-range and beyond it is half a metre.
The formula that sets your noise floor
Z is depth, f is focal length in pixels, b is the baseline between the two imagers, d is disparity in pixels, and dd is the disparity uncertainty of one match. Everything here follows from the second line: depth error grows with the square of range and falls in direct proportion to focal length and baseline. Compact USB stereo modules run baselines of roughly 50–95 mm — wider than the 60 mm human interocular, but without the temporal fusion a brain applies to the pair. Doubling the baseline halves the error; doubling the range quadruples it. The baseline trade-offs have their own guide in choosing a stereo camera baseline, and the behaviour at distance in long-range stereo accuracy with a wide baseline.
Worked example: reproducing an 80 cm jump at 3 m on a 95 mm baseline
Inputs, with where each comes from:
- Baseline b = 95 mm, the extended-baseline module class this camera belongs to.
- Stream width 640 pixels, horizontal field of view about 80°, so f = (640 / 2) / tan(40°) ≈ 380 px.
- A wall at Z = 3,000 mm, mid-range for this class.
- The observed jump itself: 800 mm between frames on a still scene.
Rule in words: disparity equals f·b divided by depth, so evaluate disparity at both depths and read off the pixel disagreement the jump represents.
Arithmetic:
- f·b = 380 px × 95 mm = 36,100 mm·px
- d at 3,000 mm = 36,100 / 3,000 = 12.0 px
- d at 3,800 mm = 36,100 / 3,800 = 9.5 px
- The jump is a 2.5 px disagreement of the matcher, frame to frame.
- As a rate: one disparity pixel costs Z² / (f·b) = 9,000,000 / 36,100 ≈ 250 mm at this range.
Decision: on this geometry, a jump up to about a metre is two or three disparity pixels of disagreement — normal matcher behaviour on weak texture, not a camera fault. If you need ±20 mm repeatability at that range, the matcher would have to hold dd ≤ 0.08 px (20 × 36,100 / 9,000,000); no preset does that on a blank wall. You add texture, shorten the range, or filter over time — those are the three real levers.
Causes in order of probability, each with its test
- Weak texture: dark, flat, glossy or IR-saturated surfaces. The most common cause by far. Test: save the IR or left image at the same instant; the region that jumps reads flat white, flat black or mirror. Fix: add texture, two sections down. A total match failure on a textureless surface is the same mechanism taken to its limit, as in a black depth image on a textureless surface.
- Range. The square law has put your tolerance below one disparity pixel. Test: read your cost per pixel from the table below; if the tolerance you need is smaller than the entry for your range, this is your cause. Fix: closer, more pixels, or a wider baseline.
- Auto-exposure hunting or projector washout. Exposure that re-prices every frame moves every match; a near, bright surface can also saturate the projected pattern. Test: fix exposure and gain manually and watch 100 frames; if the scatter halves, you found it. Fix: locked exposure, more distance to the nearest reflective object, lower emitter power where the interface allows.
- Wrong matches reported as valid. Test: enable the confidence and edge filters, or decode the confidence map yourself — confidence image bit flags — and re-measure the jumping region. Fix: mask low-confidence pixels with the IR image as referee, per masking invalid pixels with the IR stream.
- The camera moves even though the scene does not. A rolling-shutter pair bolted to a vibrating frame smears the match. Test: watch a high-contrast edge in the color stream frame to frame; any shimmer is motion. Fix: a rigid mount on a still structure, per mounting stillness during capture. Cameras that fuse an IMU can also import jitter through the motion model; see the stereo depth jitter and IMU drift walkthrough.
What one disparity pixel costs at each range
Computed as Z² / (f·b) with f·b = 36,100 mm·px from the worked example. The second column assumes 0.2 px of subpixel match noise, a common figure for block matching and an estimate rather than a specification:
| Range | 1 disparity pixel | 0.2 px subpixel noise |
|---|---|---|
| 1 m | 28 mm | 6 mm |
| 2 m | 111 mm | 22 mm |
| 3 m | 250 mm | 50 mm |
| 4 m | 443 mm | 89 mm |
| 5 m | 693 mm | 139 mm |
| 6 m | 997 mm | 199 mm |
Read it as a budget: at 5 m the matcher must hold better than one pixel for the scatter to stay under about 70 cm. Your own numbers rescale as 1 / (f·b), so a longer focal length or a wider baseline divides every entry.
The fixes, in the order that pays off
- Lock exposure and gain. Free, reversible, and it removes a whole noise class before you change any hardware.
- Add texture. Scatter film, matte spray or a sticker grid on what you may mark; an IR pattern projector or flood illuminator where you may not mark the part. The projector already inside the camera carries you a metre or two; beyond that, added IR texture extends the range.
- Change the geometry. Doubling the stream width to 1280 pixels doubles f to about 762 px, halving the per-pixel cost to 124 mm at 3 m. Halving the range quarters it to 62 mm. Doubling the baseline halves it, at the price of a bigger camera and a shorter overlap zone — the trade the baseline guide walks through.
- Filter over time. A median of 5 frames deletes single-frame outliers, and averaging N frames then cuts random scatter by roughly √N: nine frames turn the 50 mm single-frame figure from the table into about 17 mm. This holds only while scene and camera stay still. For learned-disparity pipelines there is a separate noisy DNN stereo disparity walkthrough.
- Mask what you cannot fix. Some surfaces will not hold a match; excluding them beats reporting noise, and corner behaviour is often the worst of it — stereo depth corner noise in point clouds.
When stereo is the wrong tool
Put the bar down before you tune. One commercial stereo camera carries a specified accuracy of 1% of Z at 1 m, and the square law means that same disparity noise gives about 2% at 2 m and 3% at 3 m — the relative error grows linearly with range. Decide from that: if you need better than roughly 2% of range beyond mid-range, on surfaces you are not allowed to texture, matcher tuning will not close the gap. Change the sensing method.
When the surface supplies no texture and you cannot add any, use a camera that brings its own. A projected structured-light 3D camera such as the MV-DPS200P-02 paints a speckle pattern onto the part, so the matcher always has features, whatever the finish.
- Type
- Stereo / structured light
For larger working volumes, a laser galvanometer stereo camera such as the MV-DLS300P-04 scans its pattern across the scene, and a time-of-flight unit like the MV-DT01WMU measures the return directly, with noise that does not ride on surface texture.
- Type
- Stereo / structured light
- Type
- Depth / ToF camera
Checks before you blame the camera
- The IR frame shows genuine texture in the region that jumps.
- Exposure and gain are locked, not automatic.
- The measured scatter sits within about one disparity pixel of the table entry for your range.
- Confidence filtering is on, and masked pixels are excluded from the measurement.
- The camera mount is as still as the scene.
- The values scatter around a centre: values pinned to one number point at the range window instead, per depth stuck at a fixed value.
If all six hold and the jumps persist, send the depth and IR frames through the contact page and we will read the scene with you. To re-equip instead, the 3D sensors category lists the sensing families, the camera finder filters them by type, and more depth-camera diagnostics are indexed on the 3D vision topic page.
Questions
How much depth scatter is normal on a still scene?
Treat one disparity pixel as your unit of scatter: it costs Z² / (f·b). On the worked geometry, a 380 px focal length with a 95 mm baseline, that is about 28 mm at 1 m, 250 mm at 3 m and 693 mm at 5 m. A still scene wandering within one disparity pixel is healthy; wandering several pixels points at texture or exposure, not a broken camera.
Does raising the stream resolution reduce the jumps?
Yes, and linearly where it matters: doubling the image width from 640 to 1280 pixels doubles the focal length in pixels, so one disparity pixel costs half as much depth, about 124 mm instead of 250 mm at the worked range. You also double the pixels available for subpixel matching. The cost is bandwidth and frame rate, so spend it only on the range where you need the tolerance.
Is averaging frames on a still scene legitimate?
Yes, and it is the cheapest accuracy you will buy. Averaging N frames of a static scene cuts random disparity scatter by roughly the square root of N: nine frames turn a 50 mm single-frame scatter at the worked range into about 17 mm. Run a small median first to delete single-frame outliers, then average. It holds only while both the scene and the camera stay still, because motion breaks the assumption the filter rides on.
Can I request more precision when I open the stream?
No. The width, height, format and frame rate you pass at start configure the transport, not the accuracy. Precision lives in three later places: the matcher preset, the exposure and gain settings, and the per-frame post-processing filters. A precision argument inside the stream configuration does not exist, and the range format's step size is far finer than the noise you are fighting anyway.
When should I stop tuning stereo and change sensing technology?
Set the bar before tuning: if you need better than about 2% of range beyond a few metres on surfaces you cannot texture, stereo will not hold it. A specified stereo accuracy of 1% of Z at 1 m becomes roughly 2% at 2 m and 3% at 3 m with the same disparity noise, because error scales with the square of range. Below that bar, projected structured light or time of flight is the right sensing method.


