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

使用StereoBM获取绝对视差以测量绝对距离的技术咨询

如何从立体图像得到绝对视差并测量绝对距离

嘿,这个问题问到点子上了!你现在用StereoBM得到的视差图确实是相对尺度的灰度表示——白色只是当前计算范围内的最大视差像素值,和真实物理距离完全不挂钩。要拿到能测绝对距离的绝对视差,得走完「相机标定→立体校正→视差还原→深度计算」这一套流程,咱们一步步说:

为什么当前结果是相对的?

cv2.StereoBM.compute()返回的其实是16位有符号整数的视差数据,你把它直接当灰度图显示时,OpenCV会自动把数值归一化到0-255范围,所以白色只是相对最大值,丢失了真实的像素视差数值,更没法关联到物理尺度。

拿到绝对视差&测量距离的关键步骤

1. 先完成双目相机标定

这是核心前提——你必须知道左右相机的内参(焦距、主点坐标)、畸变系数,以及两相机之间的平移/旋转关系(基线距离就藏在平移矩阵里)。

  • 用棋盘格标定板拍摄多组左右视角的图像,然后用cv2.calibrateCamera()分别标定单目相机,再用cv2.stereoCalibrate()得到双目系统的外参(旋转矩阵R、平移矩阵T)。
  • 标定后你能拿到焦距f(像素单位,从内参矩阵的[0,0]或[1,1]位置取值),以及基线B(物理单位,比如米,一般是平移矩阵T的x分量绝对值,因为双目相机通常水平放置)。

2. 对图像做立体校正

标定后需要把左右图像校正到极线平行的状态,这样StereoBM的匹配精度会更高,也方便后续的视差转深度:

  • 用cv2.stereoRectify()计算校正映射,再用cv2.remap()分别对左右灰度图做校正。

3. 还原真实的绝对视差数值

StereoBM的视差结果是乘以16存储的(为了保留小数精度),所以要先还原成真实的像素视差:

# 从StereoBM得到原始视差(16位整数)
disparity_raw = stereo.compute(l1_rectified, l2_rectified)
# 转换为浮点型的真实视差(像素数)
disparity = disparity_raw.astype(np.float32) / 16.0
# 过滤无效视差(比如小于等于0的区域,代表匹配失败)
disparity[disparity <= 0] = np.inf

4. 用三角测量公式计算绝对距离

有了视差、焦距和基线,就能用经典的立体视觉公式计算深度(绝对距离):

depth = (f * B) / disparity
  • depth的单位和基线B一致(比如米),值越小代表物体越近。

完整示例代码

import cv2
import numpy as np

# 替换成你自己标定得到的参数!
fx = 600.0  # 相机焦距(像素单位)
B = 0.12    # 双目基线(米,比如12厘米)

# 读取图像
imgL = cv2.imread("left_img.jpg")
imgR = cv2.imread("right_img.jpg")
grayL = cv2.cvtColor(imgL, cv2.COLOR_BGR2GRAY)
grayR = cv2.cvtColor(imgR, cv2.COLOR_BGR2GRAY)

# 这里省略标定和校正步骤,假设你已经得到校正后的grayL_rectified和grayR_rectified
# 如果没校正,也可以直接用原始图,但匹配精度会下降

# 立体匹配
stereo = cv2.StereoBM_create(numDisparities=128, blockSize=15)
disparity_raw = stereo.compute(grayL, grayR)

# 还原真实视差
disparity = disparity_raw.astype(np.float32) / 16.0
disparity[disparity <= 0] = np.inf

# 计算深度图(米)
depth_map = (fx * B) / disparity

# 可视化深度图(归一化到0-255方便显示)
depth_vis = cv2.normalize(depth_map, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U)
cv2.imshow("Absolute Depth Map", depth_vis)
cv2.waitKey(0)
cv2.destroyAllWindows()

注意事项

  • 标定的精度直接决定了深度测量的准确性,建议拍摄15-20组不同角度、不同距离的棋盘格图像来标定。
  • 视差图里难免会有噪声或匹配错误的区域,可以用cv2.filterSpeckles()、中值滤波或者双边滤波来优化。
  • 如果你的相机是已经预校正好的双目模组(比如Intel RealSense),可以直接拿到官方提供的内参和基线,不用自己标定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:58:27