3D visionTroubleshooting

Stereo depth returns 0 at the bottom of the image: why

Why stereo depth returns 0 in the bottom rows: the rectification valid region, disparity range limits and the fixes, with the math to size them.

LumaSpec Vision12 min read Share on LinkedIn

On this page 10 sections
  1. 01A 0 is a sentinel, not a distance
  2. 02Cause 1: rectification warps the outer rows
  3. 03Cause 2: the color camera sees more than the stereo pair
  4. 04Cause 3: the nearest surfaces exceed the disparity search range
  5. 05Cause 4: calibration drift makes the warp asymmetric
  6. 06Ten-minute tests, in order
  7. 07Fixes that survive production
  8. 08If you are choosing hardware instead
  9. 09Prevention checklist
  10. 10Questions

You query depth near the lower edge of the frame and the SDK answers 0, every frame, on every unit of the same model. Nothing is broken and there is nothing to send back. A stereo correlator can only produce disparity where three conditions hold at once: rectification left real overlap between the two images, the correlation window fits inside the frame, and the true disparity sits inside the search range.

The bottom of the frame fails all three tests first. Warp displacement is largest at the outer rows, an aligned color camera usually sees more than the stereo pair does, and the closest surfaces in the scene land there. This page names the four causes in order of probability, gives a ten-minute test for each, and works the arithmetic that tells you how far up the frame depth is trustworthy.

A 0 is a sentinel, not a distance

Depth 0 in the bottom rows does not say the surface is 0 mm from the lens. It is the value most stereo firmware writes when it has no confident match: the pixel fell outside the valid rectified region, the correlation window ran past the image edge, the true disparity exceeded the search limit, or the match score was too weak to accept. Keep the confidence channel if the camera provides one — a low-confidence match at a real distance is a different failure from a clean zero.

Your first job is to stop zeros from entering downstream math. Convert every 0 to NaN or drop the pixel before any average, minimum or robot target is computed; the pixel-to-3D query in your SDK reads the same depth map, so the zeros arrive there too. When a pixel does carry a valid value, it is a Z along the camera's own axis, and converting a pixel's Z to a true camera distance is its own small trap.

Cause 1: rectification warps the outer rows

Rectification reprojects both images so a scene point lands on the same row in left and right; that is what lets the correlator search a single row instead of a 2-D area. The reprojection is computed for the camera poses recorded at calibration. Real compact camera modules (CCMs) never sit exactly at those poses — a few tenths of a degree of rotation between modeled and real camera is ordinary — and the correction displacement grows from the warp centre outward, reaching its maximum at the frame edges. Pixels pushed inward from outside the original sensor area have no source data, so the firmware marks that outer band invalid. The bottom rows suffer most because rotation about the optical axis stacks vertical shear on top of the radial growth.

Two margins add together, and both are computable:

window margin = (W − 1) / 2 rows, for a W × W correlation window edge shift from rotation ≈ frame height × tan θ

A 15 × 15 window forfeits (15 − 1)/2 = 7 rows at each edge, because the window cannot be filled beyond the image. Rotation shear is usually larger: 1° on an 800 px tall frame moves the bottom edge by 800 × tan 1° ≈ 14 px, and 2° moves it about 28 px. Border errors are a built-in weakness of correlation stereo — a whole branch of the literature exists on reducing them — which is why vendors mask the outer rows rather than trust them. For the warp-specific failure modes underneath this one, stereo disparity map troubleshooting after rectification takes the next step.

Test: colorize the raw disparity. An invalid band that hugs the bottom (and often the top) edge with the same width on every unit of the model is geometry, not damage. A wedge that thickens toward one side points to cause 4.

Cause 2: the color camera sees more than the stereo pair

If you request depth aligned to the color image, you can ask for pixels the stereo pair never saw. These modules typically pair two grayscale sensors of one field of view with a wider color camera between them, and rectification trims the pair's usable field again. Rows that only the color camera sees have no disparity to copy, so the aligned depth map stays 0 there — usually a band at the bottom, sometimes at both edges.

The ratio is direct. With a color sensor covering 72° vertically and rectification leaving the pair 60°, the missing fraction is (72 − 60) / 72 = 17% of the rows, about 8% at each edge when the loss sits symmetrically. Substitute your own angles; the ratio does the rest.

Fix: crop the color image to the pair's field instead of stretching depth into the color frame, and design the region of interest around the smaller map from day one. Depth image field of view: why stereo coverage is smaller works the coverage arithmetic, and depth to color registration: raw versus rectified frames covers the alignment step itself.

Cause 3: the nearest surfaces exceed the disparity search range

Depth comes from disparity through:

Z = f · B / d Z_min = f · B / d_max

with f the focal length, B the baseline, and d the disparity in pixels — multiply d by the pixel pitch p to put it in length units before dividing. The search limit d_max caps the disparity, which caps how close a surface can be before its disparity falls outside the search and the correlator reports nothing: 0 again. With the camera pitched toward the work surface, the nearest visible surfaces project into the lower rows, so an undersized search range and a bottom-of-frame band of zeros are often the same fault.

Worked example, with example inputs for a typical compact module (not any specific model): f = 2.5 mm, B = 50 mm, p = 3 µm, d_max = 96 px.

Z_min = (2.5 mm × 50 mm) / (96 × 0.003 mm) = 125 mm² / 0.288 mm ≈ 434 mm

Everything nearer than about 0.43 m has no disparity, and it all lives in the bottom of the frame. What moves the number: raising the limit to 128 px gives 125 / 0.384 ≈ 326 mm, while widening the baseline to 100 mm pushes Z_min out to 250 / 0.288 ≈ 868 mm — wide baselines buy far-range accuracy and give up near range.

Fix: set the search limit from the nearest real target plus ~10% margin, not from habit, because every extra disparity step costs bandwidth and invites false matches on weak texture. Needing both 200 mm reach and long-range accuracy is a hardware decision, not a software setting. The full disparity-to-metric chain is in stereo disparity scale and calibration for depth estimates, and the quantization step in stereo depth height overestimation from disparity quantization.

Cause 4: calibration drift makes the warp asymmetric

A straight band along the bottom is design; a wedge that thickens toward one bottom corner is calibration no longer matching the mechanics. Mechanical shock, a knocked bracket, thermal cycling on an arm or a re-run calibration can each rotate a camera by a fraction of a degree, and the warp computed from the old poses then invalidates more of one side than the other. Vertical misalignment between the two images is a measurable accuracy loss in its own right in stereo performance studies, and it bites hardest at the rows farthest from the warp centre.

Three checks separate capture errors from pipeline errors: confirm the rectified pair still sits row-for-row (fixing rectification when the lines run off horizontal); re-run the SDK's rectification on recorded raw frames (checking that recorded stereo frames are truly rectified); and if you undistort with your own coefficients, confirm the direction, because inverted distortion coefficients make corrected depth look warped near the edges (why rectified depth looks warped with inverted distortion coefficients).

Fix: recalibrate on target, and let the bracket — not the cable — carry the module's load.

Ten-minute tests, in order

  1. Raw disparity first. Display the disparity map from the depth pair itself, before any alignment. Zeros there mean causes 1, 3 or 4; a clean raw map that grows zeros only after alignment means cause 2.
  2. Read the shape of the hole. A straight band hugging the bottom edge, identical on every unit, is window margin or field-of-view difference. A wedge thickening toward one corner is calibration.
  3. Walk a target in. Move a textured target toward the camera and record the distance where disparity first turns non-zero. It should land within a few percent of f·B/d_max from your settings; a much larger measured Z_min means the search limit you configured is not the one running.
  4. Count the window. Read the window size from the SDK configuration and compare (W − 1)/2 with the measured band width.
  5. Change nothing yet. If the pattern shifts after the camera is bumped or re-calibrated, it is mechanical; if it is identical across units and sessions, it is by design.

Fixes that survive production

  1. Mask before you measure. Build the valid-region mask once per model from a textured-wall capture and apply it before averaging, min/max or point extraction; selecting valid pixels for an average depth shows the pattern.
  2. Crop, do not stretch. Crop color to the pair's valid field when you need overlays; never resample depth into rows that had no disparity.
  3. Mount for the middle of the frame. Aim the module so the region of interest sits well inside the valid band; the 3D camera working distance and positioning guide covers the geometry.
  4. Set d_max from Z_min. Compute f·B/d_max for the nearest target and add margin; in the example above, 128 px instead of 96 px moved the reachable minimum from 434 mm to 326 mm.
  5. Carry validity with the data. Store the mask, the disparity scale and the rectification metadata alongside every recording, so a zero is still diagnosable months later.

If you are choosing hardware instead

When the zeros come from a kit build you inherited — mismatched sensors, hand-rolled rectification — the durable fix is an integrated 3D camera calibrated as a unit: depth arrives from the sensor in a metric frame, and the valid region is a property of the housing that you measure once and then own. Two integrated families from the shop's stereo and structured-light range:

3D sensorsHikrobot MV-DLS300P-04 Laser galvanometer stereo cameraMV-DLS300P-04
Type
Stereo / structured light
$16,579.00 · quotedView and quote
3D sensorsHikrobot MV-DPS200P-02 Projected structured-light 3D cameraMV-DPS200P-02
Type
Stereo / structured light
$8,829.00 · quotedView and quote

The MV-DLS300P-04 is a laser galvanometer stereo camera; the MV-DPS200P-02 is a projected structured-light 3D camera. Structured light and speckle projection sidestep the correlation-window margin entirely, while keeping their own valid region and nearest-measurable-distance limit in the data sheet. For volume-measurement and logistics loading, the shop also carries dedicated logistics 3D cameras — see the stereo and structured-light 3D sensors category.

Zeros at the border are geometry. Wrong disparities scattered across the whole frame are a different disease: correlation noise on weak texture, or, with neural stereo models, network error. Smoothing raw stereo depth into usable data covers the classical cleanup, and the noisy DNN stereo disparity troubleshooting page treats the neural-model case. When no depth streams at all, start at acquisition rather than geometry: the timeout with ping working but no pixel data pattern is the usual match.

Prevention checklist

  • Map the valid region at commissioning. One capture of a textured wall at working distance gives the exact rows and columns to trust; write them into the station file.
  • Keep the region of interest inside the central 80% of rows until you have measured your own band; the outer edges carry the warp maximum and the window margin.
  • Derive d_max from the nearest real target. Compute Z_min = f·B/d_max, add roughly 10% margin, and revisit whenever the mounting height changes.
  • Store validity, confidence and disparity scale with every recording. A zero you cannot explain later is a zero you will debug twice.
  • Re-capture the wall after any mechanical work. A touched bracket or a re-run calibration changes the band; compare widths before production resumes.
  • Treat 0 as no-data end to end. NaN in analysis, mask in overlays, error state in robot logic.

Next step: capture the wall, fix your valid region, and check that the nearest target clears the Z_min your search range implies. To compare integrated modules with a known working range, open stereo and structured-light 3D sensors or step through the camera configurator; more depth-map failure modes are collected on the 3D vision topic page, and integration questions reach the applications team through the contact page.

Cameras3D sensors

Laser profilers and stereo 3D cameras

170 models · from $699.00

Questions

Does a depth of 0 mean the object is touching the camera?

No. Zero is the sentinel most stereo firmware writes when no confident disparity exists: the pixel is outside the valid rectified region, the correlation window ran off the image, or the true disparity exceeded the search limit. The closest measurable surface returns the smallest non-zero value your Z = f·B/d conversion allows, never a clean 0. Convert zeros to NaN or drop them before any average, minimum or robot target uses the map.

How many rows does the correlation window actually invalidate?

(W − 1)/2 rows at each edge: a 15 × 15 window costs 7 rows top and bottom because the window cannot be filled beyond the frame. Rectification warp adds on top of that, roughly frame height × tan θ, so 1° of rotation on an 800 px tall frame shears the bottom edge by about 14 px. Measure the combined band once on a textured wall and hard-code it as the valid region.

Can I interpolate the zero bottom rows into real depth?

For display, overlays and record-keeping, filling from the nearest valid rows is harmless. For measurement, no: interpolated pixels carry no independent disparity, so any height, volume or position computed from them is fiction that happens to look smooth. If a downstream tool demands a rectangular map, ship the validity mask alongside it and let the tool exclude the missing rows.

Why is the color image full frame while the aligned depth map is not?

The color sensor and the stereo pair rarely share a vertical field of view, and rectification narrows the pair further. Alignment can only copy disparity into rows where the pair actually saw the scene, so a wider color camera produces rows with no depth partner. Crop the color image to the pair's field, or accept a depth map smaller than the color frame.

Does this also happen on factory-calibrated 3D cameras?

Yes, in a smaller dose. Factory calibration removes your warp errors, but the correlation-window margin and the disparity search limit still apply, so every stereo camera has a valid region and a minimum measurable distance. The practical difference is that the working range is in the data sheet, so you can size the mounting height before the camera arrives instead of discovering Z_min on the bench.