You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于立体图像视差图计算物体实际距离的两类技术问题咨询

Hey, let's break down your two questions step by step, using your code as a reference:

1. Why is my calculated Depth negative?

There are two main reasons for negative depth values in your implementation:

  • OpenCV StereoBM's disparity output format: The stereo.compute() method returns a 16-bit signed integer disparity map. Actual valid disparity values are stored as disparity_value / 16, and failed matches will result in negative values. You’re using raw integer values directly in your depth calculation, so negative disparities lead to negative depths.
  • Left/right image order mismatch: StereoBM.compute() requires the first parameter to be the left image and the second to be the right image. If you swapped them, disparity would be calculated as right_x - left_x (instead of the correct left_x - right_x), resulting in negative values across the board.

To fix this, normalize the disparity map and filter out invalid values first. Here’s adjusted code:

import numpy as np
import cv2
from matplotlib import pyplot as plt
%matplotlib inline

imgL = cv2.imread('C:/Users/Akash Jain/Documents/ZED/LeftDepth/left000005.png', 0)
imgR = cv2.imread('C:/Users/Akash Jain/Documents/ZED/RightDepth/right000005.png', 0)

stereo = cv2.StereoBM_create(numDisparities=16, blockSize=5)
disparity = stereo.compute(imgL, imgR)

# Convert to float and restore actual disparity values (divide by 16)
disparity = disparity.astype(np.float32) / 16.0
# Filter out invalid (negative/zero) disparities
valid_mask = disparity > 0.0

# Calculate depth only for valid pixels
baseline = 0.12  # ZED's baseline is 12cm = 0.12m
focal_length_pix = 672  # Use your actual pixel focal length
D = np.zeros_like(disparity)
D[valid_mask] = (baseline * focal_length_pix) / disparity[valid_mask]

print("Disparity:", disparity)
print("Depth:", D)
plt.imshow(disparity, 'gray')
plt.show()

2. How to get the actual object distance (in meters) from the Depth matrix?

The Depth matrix gives per-pixel distance values, so you need to isolate the pixels corresponding to your target object first, then compute a representative value (average or median works best) for that region. Here are two practical approaches:

Option 1: Manual ROI selection (simple for testing)

If you know the object’s approximate position, define a Region of Interest (ROI) and calculate the average depth in that area:

# Adjust these coordinates to match your object's position in the image
x1, y1 = 100, 200  # Top-left corner
x2, y2 = 300, 400  # Bottom-right corner

# Extract ROI from depth matrix
roi_depth = D[y1:y2, x1:x2]
# Filter out invalid depth values
valid_roi_depth = roi_depth[roi_depth > 0]
# Use median for robustness against outliers, or mean for simplicity
object_distance = np.median(valid_roi_depth)

print(f"Object distance to camera: {object_distance:.2f} meters")

Option 2: Automatic object detection (for real-world use)

Use image segmentation or contour detection to automatically isolate the object’s pixels:

# Threshold the left image to highlight the object (adjust threshold value as needed)
ret, thresh = cv2.threshold(imgL, 127, 255, cv2.THRESH_BINARY_INV)
# Find object contours
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

if contours:
    # Assume the largest contour is your target object
    max_contour = max(contours, key=cv2.contourArea)
    # Create a mask for the object
    mask = np.zeros_like(D)
    cv2.drawContours(mask, [max_contour], 0, 255, -1)
    # Extract valid depth values from the masked region
    valid_depth = D[mask == 255]
    valid_depth = valid_depth[valid_depth > 0]
    
    if len(valid_depth) > 0:
        object_distance = np.median(valid_depth)
        print(f"Object distance to camera: {object_distance:.2f} meters")
    else:
        print("No valid depth values found for the object.")
else:
    print("No object contours detected.")

Critical parameter check

Ensure your focal length value is correct: The formula Depth = (Baseline * Focal Length) / Disparity requires the focal length to be in pixel units (not physical units like meters). For ZED cameras, get the exact pixel focal length from the ZED SDK or camera calibration data—your current 0.70 * 672 seems off, so double-check this to guarantee meter-scale accuracy.


内容的提问来源于stack exchange,提问作者Akash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:38:10