A stereo depth camera hands you depth in millimetres, but underneath it matched disparity: the horizontal shift, in pixels, between the left and right images. That pixel shift decides which distances the camera can measure at all, how accurate each one is, and why the valid range moved when you changed resolution. This page gives you the conversion and its inputs, the window arithmetic behind the disparity shift setting, the 1/32-pixel units raw values arrive in, and a worked example that sizes the depth window for a robot gripper working from 0.10 to 0.30 m.
From disparity to depth: the conversion
Depth, baseline and disparity are bound by one line:
f_px is the focal length in pixels, B is the baseline between the two cameras, and d is the disparity in pixels. Keep B and Z in the same unit, metres with metres or millimetres with millimetres, and Z comes out in that unit. Pixels cancel between f_px and d, so those two carry no unit.
f_px follows from the rectified image width and the horizontal field of view:
At a 90° HFOV, tan(45°) = 1 and f_px is simply half the image width. Why focal length is quoted in pixels at all, and how to convert millimetres to pixels exactly, is on our focal length in pixels page. The calculator below does the millimetre side from sensor and scene.
The 1/d shape drives everything else. Doubling the distance halves the disparity, so far depths are always the tight resource. Depth error follows the same shape: an error of Δd pixels bends depth by ΔZ/Z ≈ Δd/d, so matching error hurts most where disparity is smallest, at the far edge of any window. Z in a depth map is also the distance along the camera axis, not the slant range to an off-axis pixel; Z in the map versus true distance covers that correction.
Where f_px and the baseline come from
Take both from calibration, not from hope. The rectified stream's fx, the focal length in pixels from the calibration matrix, is f_px. The baseline is the distance between the two cameras' optical centres. Multiply them once and keep the product f·B as a single rig constant in pixel-metres; every window decision below uses only that product.
An integrated module's SDK publishes fx and the baseline after calibration. If you build the stereo rig yourself from two area scan cameras, the calibration routine returns fx, and with intrinsics already known an extrinsics-only stereo calibration recovers the baseline. How large to make that baseline in the first place, near-field accuracy against far reach, is the baseline distance choice.
What the raw numbers mean: 32nds of a pixel and depth scales
Depth and disparity are different buffers with different units, and mixing them is the classic error. Depth pixels are integers in a depth scale the API reports, 1 mm per unit being typical, so a stored 300 reads 0.300 m. Converting raw depth values to metres shows the query and the arithmetic.
Disparity, where the SDK exposes it, arrives as integers in 1/32-pixel fixed point: the engine keeps sub-pixel precision without floats. Divide by 32 before any formula, so a raw 4000 is 4000/32 = 125 px. Converted values should fall between the shift and shift + 126; if yours sit outside that band, check whether the conversion node includes the shift and offset accordingly.
When only depth is exposed, recover disparity by inverting the conversion, d = f·B/Z pixel by pixel, or by running the SDK's depth-to-disparity node, which returns 32nds including the shift. The resulting depth bands are not fixed millimetres: one disparity step is a hair's breadth near the camera and a long throw far away.
Disparity shift: a fixed window you can slide
A stereo engine never searches every disparity from zero to infinity. Many integrated depth engines match over a fixed span of 126 disparities and expose only where that span starts, as the disparity shift setting, in pixels. A pixel matched at d_m has effective disparity d_m + shift, so the window covers shift to shift + 126 and the returnable depths are bounded at both ends:
A larger shift slides the whole window closer; a smaller shift reaches farther out. Two rules keep the edges honest. At the far edge, relative error is Δd/d with d equal to the shift, so a 1-px shift nominally reaches f·B but returns unusable depth there; keep the smallest disparity you actually rely on at 16 px or more, where 0.1 px of matching error stays under 0.6%. At the near edge, leave the window a few pixels wider than the scene so edge disparities match at full strength.
For a task spanning Z_near to Z_far, the window must hold this many disparities:
If the span exceeds 126, no shift setting covers the task in one window. Run two shift profiles or drop the resolution; the worked example below does both.
Worked example: a gripper cell from 0.10 to 0.30 m at 1280 × 800
Inputs: rectified width 1280 px and 90° HFOV from the stream setting and module datasheet, baseline B = 0.050 m from the mechanical datasheet, task depths 0.10–0.30 m from the cell itself, where the robot approaches at 0.30 m and grips at 0.10 m. The rule is Z = f·B/d with the window bounds minZ = f·B/(shift + 126) and maxZ = f·B/shift.
- Focal length in pixels: f_px = (1280 / 2) / tan(45°) = 640 px. Rig constant: f·B = 640 px × 0.050 m = 32 px·m.
- Disparity at the far task edge: d = 32 / 0.30 = 106.7 ≈ 107 px. At the near edge: d = 32 / 0.10 = 320 px.
- Required span: 320 − 107 = 213 px. The window holds 126 px, so one setting cannot cover the task: shift ≤ 107 and shift ≥ 320 − 126 = 194 contradict each other.
- Best single window pinned at the far edge: shift = 107 covers disparities 107 to 233, which is Z from 32 / 233 = 0.137 m to 32 / 107 = 0.299 m. Call it 0.14–0.30 m; the 0.10–0.14 m band returns no depth.
- Second profile for the near band: shift = 194 covers 194 to 320, Z from 32 / 320 = 0.100 m to 32 / 194 = 0.165 m. Profiles 107 and 194 together cover the cell, overlapping around 0.14–0.16 m.
- Half-resolution alternative at 640 × 400: f_px = 320, f·B = 16 px·m, disparities halve to 53 px at 0.30 m and 160 px at 0.10 m. The span of 107 px now fits one window: shift = 50 covers 50 to 176, Z from 16 / 176 = 0.091 m to 16 / 50 = 0.320 m, the whole task in one profile.
Decision: at full resolution the cell needs two shift profiles, 107 for the 0.14–0.30 m approach and 194 for the 0.10–0.16 m grip band. At half resolution one profile, shift 50 covering 0.09–0.32 m, does the whole job. Far-edge accuracy holds either way: ΔZ/Z ≈ Δd/d with Δd = 0.1 px gives 0.09% at d = 107, about ±0.3 mm at 0.30 m, and 0.19% at d = 53, about ±0.6 mm.
Two profiles or half resolution: the decision
| Route | Shift | Depth covered | Profiles | Cost |
|---|---|---|---|---|
| Full resolution, near and far | 107 and 194 | 0.14–0.30 m and 0.10–0.16 m | 2 | the robot program switches profiles inside the 0.14–0.16 m overlap |
| Half resolution, single | 50 | 0.09–0.32 m | 1 | half the lateral pixels; far-edge depth error about doubles, to ±0.6 mm at 0.30 m |
Take the two-profile route when the task needs the full 1280-pixel lateral detail or the cell already reconfigures the depth engine per approach. Take the single profile when depth must stream continuously, for conveying, bin scanning or path following, and ±0.6 mm at the far edge sits inside tolerance. In every profile, hold the far-edge disparity at or above the 16-px floor from the last section; that floor, not the shift's nominal reach, is what protects accuracy.
Checks before you trust the window
Bench-check the rig constant before production. Place a matte target at a measured distance inside the window, compute d = f·B/Z for it, and compare with the raw value divided by 32; repeat at a second distance. If both readings miss by the same factor, f·B is wrong, so recalibrate rather than nudging the shift to fit.
Then watch the edges in the real scene. Pixels that vanish at the far edge have true disparity below the shift; pixels that vanish at the near edge sit above shift + 126. The fix direction is known in both cases, but when both edges matter and the span exceeds 126, no shift helps: go to two profiles or lower resolution. Read the confidence image alongside the depth, because it separates a window miss from a matching failure caused by poor texture or exposure. Smooth residual noise only after the window is right; smoothing raw stereo depth cannot rescue pixels the window never measured.
When a disparity depth camera is the wrong tool
Everything above assumes the scene gives the matcher texture to lock onto. Matte, patterned or naturally varied surfaces work; black rubber, polished plastic and bare machined faces starve the matcher at any window setting. Three escapes, in the order most cells reach for them.
A projected structured-light camera injects its own pattern, so the texture question disappears: MV-DPS200P-02 is that class of sensor.
- Type
- Stereo / structured light
When the camera or the part sweeps a wider depth span than any single window and profile switching is impractical, time-of-flight reads range from returned light directly, with no disparity search to confine: MV-DT01WMU is a ToF sensing camera of that kind.
- Type
- Depth / ToF camera
For a calibrated profile of one surface at a fixed stand-off, seam, edge or flushness, a laser profiler such as MV-DP4180-03P scans a laser line across the part and measures depth by triangulation.
- Type
- Laser profiler
For what millimetre-class resolution means at 0.05–0.15 m, see the close-range depth camera guide. All of these classes sit in the 3D sensors range, alongside the laser profilers and stereo modules the window arithmetic above applies to.
Set-up checklist
- Compute f_px from the rectified width and HFOV, or take fx from calibration, and keep f·B as the rig constant. Every later decision uses only that product.
- Convert the task's closest and farthest depths to disparities. A span above 126 px means two profiles or lower resolution, planned before wiring anything.
- Set the shift from the far edge, a margin of roughly 10 px below the far-edge disparity when the span allows it, so the farthest work keeps matching margin.
- Confirm the near edge: shift + 126 must exceed the closest disparity, or the closest work returns holes.
- Re-derive the shift after every resolution or calibration change.
- Verify with two measured targets, then watch the confidence image for window misses against texture failures.
If you are sizing this for a real cell, the camera finder filters depth cameras by type and the configurator walks the rest of the chain. Send us your near and far depths through the contact page and we will check the window arithmetic with you; the 3D topic page gathers the neighbouring depth-conversion guides.
Questions
Are disparity and disparity shift values in pixels or in 1/32-pixel units?
Conceptually both are in pixels. In most SDKs they travel as integers in 1/32-pixel fixed point, so a raw disparity of 4000 means 125 px. A shift value that looks about 32 times too large is in the same 32nds; divide by 32 before using it in the depth formulas. Depth values are a different stream with their own scale, usually 1 mm per unit.
Why does depth turn invalid beyond a certain distance?
Because the true disparity has dropped below the shift: the matcher finds no answer inside its window and returns an invalid pixel, which most SDKs mark as zero depth or a cleared bit in the confidence image. Lower the shift to reach farther, but first confirm from the confidence image that the hole is a window miss rather than a texture or exposure failure, since lowering the shift also pulls the near edge out.
Does raising the camera resolution extend the usable depth range?
No. Resolution multiplies focal length in pixels, so every disparity in the scene grows with it: the span a fixed window must hold, f·B × (1/Znear − 1/Zfar), grows in direct proportion. With the shift held fixed, both window edges move away from the camera. Halving the resolution halves that span — 213 px becomes 107 px in the worked example — at the cost of doubled relative depth error.
How accurate is stereo depth at 0.30 m?
Relative depth error is about the disparity error divided by the disparity. At a far-edge disparity of 107 px with 0.1 px of matching error, that is 0.1/107 ≈ 0.09%, or about ±0.3 mm at 0.30 m. Calibration, texture and lighting dominate in practice, so expect a few tenths of a millimetre to a millimetre; a laser profiler at a fixed stand-off does better.
Is the disparity shift already applied inside the depth values the API returns?
In depth engines that use a shift, yes: move the shift and the far edge of valid depth moves with it, no extra step on your side. The same applies in reverse: a depth-to-disparity conversion node returns disparity that includes the shift, in 1/32-pixel units. Check it by moving the shift one pixel and watching the far edge of valid depth move with it.


