ELAI S.r.l.

相机看到了零件,它究竟有多远?

相机看到了零件,它究竟有多远? 通过完整算例解释方法、假设与局限。

相机看到了零件,它究竟有多远?

认出零件,不代表知道距离

相机给出零件中心在图中的点,但机器人抓取需要空间坐标。一个像素包含多少距离信息?我们推导单目歧义,说明双校准相机增加什么,再计算一像素误差如何改变深度。结果是已执行的理想几何,不是机器人实测。

一个像素确定一条射线,而非唯一点

设理想针孔相机,X、Z 用米,Z 沿光轴为正,f 用像素,u 已减主点。投影 u=fX/Z,同时正比例缩放 X、Z 不改变 u,因此只知比例而非米制尺度。f=800 时,(0.2,2) 与 (0.4,4) 均给 u=80 像素。

u = f X/Z; f (aX)/(aZ) = f X/Z, a>0

单目仍可利用已知平面、尺寸、校准运动或学习规律。深度模型添加训练假设,并非无条件消除单投影歧义。若尺寸未知,把“看起来小”解释为“更远”是先验选择,不是保证的几何测量。

双相机让一个差值可观测

第二相机沿 X 相距 B,光轴平行、焦距相同;图像已校正、坐标居中且正确匹配同一空间点。u_L=fX/Z,u_R=f(X−B)/Z,相减消去 X,得视差 d=u_L−u_R=fB/Z。已知基线 B 提供单视图缺少的米制长度。

d = u_L−u_R = fB/Z; Z = fB/d, d>0

f=800 像素、B=0.1 m 时 fB=80 像素米,Z=2、10 m 对应 d=40、8 像素。X=0.2、Z=2 时 u_L=80、u_R=40,Z=80/40=2 m,像素单位抵消。零、负或无效视差须核查约定与匹配,不能直接当正深度。

物体越远,一个像素影响越大

固定 f、B,dZ/dd=−fB/d²,局部 δZ≈−fBδd/d²。负号表示视差增大、深度减小,模表示敏感度:两米处 0.05 m/像素,十米处 1.25。它们是局部斜率,不是标准差或置信区间。

不线性化时,d=40±1 给出 80/41≈1.951219 至 80/39≈2.051282 m;d=8±1 给出 80/9≈8.888889 至 80/7≈11.428571 m。求逆使误差区间不对称;若视差区间触及零,本模型深度上界不再有限。

Z(m)d(px)Z(d+1)(m)Z(d−1)(m)
2.040.01.951222.051282
10.08.08.88888911.428571
视差接近零时深度快速增加。误差棒代表 ±1 像素,不是置信区间。理想几何,未测真实相机。
视差接近零时深度快速增加。误差棒代表 ±1 像素,不是置信区间。理想几何,未测真实相机。

几何不能代替校准和真实测试

OpenCV 教程说明立体关系及低纹理、边缘、噪声等匹配限制。我们未执行 StereoBM 或比较深度网络。公式假定匹配正确,错配也可产生有限但无意义的数。焦距、基线、畸变和同步误差不在 ±1 像素棒内;这里只扰动 d,固定 f、B。

工业与协作机器人是 EL-AI 拟探索方向,本例不证明已有安装。用于抓取前须验证相机、相机到机器人坐标、不确定性及物理任务。本推导不认证安全、精度或抓取成功,标量求逆成本也不代表整幅匹配成本。

单像素给方向,校准立体几何可给距离,物理验证才决定是否足够完成任务。越远越敏感于视差误差。认出零件有用,却不足以定位夹爪。

OpenCV 4.13.0 — Stereo depth geometry.

import json,sys
from pathlib import Path
f=800.;B=.1
rows=[]
for Z in [2.,10.]:
 d=f*B/Z;rows.append(dict(Zm=Z,disparityPx=d,lowZm=f*B/(d+1),highZm=f*B/(d-1),localSensitivityMPerPx=f*B/d**2))
assert f*.2/2==f*.4/4==80
assert rows[0]['disparityPx']==40 and rows[1]['disparityPx']==8
r=dict(python=sys.version.split()[0],seed=None,scope='Ideal calibrated rectified pinhole geometry; no real camera or robot measurement',focalPx=f,baselineM=B,rows=rows,disparityGrid=list(range(2,81)),depthGrid=[f*B/d for d in range(2,81)],scaleAmbiguity=[[.2,2.,80.],[.4,4.,80.]])
Path(__file__).with_name('results.json').write_text(json.dumps(r,indent=2),encoding='utf8')

代码、数据与说明 · JSON. 教学计算使用 Python 3.14.0,图使用 Matplotlib 3.11.2。分析由 AI 辅助,不声称经过同行评审或人工审核。原创 ImageGen 封面仅作示意,不记录 EL-AI 人员、场所或实际安装。来源查阅于 2026 年 10 月 25 日。