physics
世界与成像
虚拟相机是怎么从一个三维场景算出一张图的。公开模型,不公开实现。
引擎是闭源的,模型不是。 你凭什么相信虚拟设备算出来的数是对的?——因为我们把模型完整写出来,你可以自己验算。 这是这一章存在的唯一理由。
场景表示
台面上的东西用解析几何描述,不做三角网格渲染:
- 平面片:标定板、工件表面、载具;含位姿
T_W_Obj与尺寸; - 图案:圆点阵列、棋盘格、基准点(fiducial)、划线;定义在平面片的局部 2D 坐标里;
- 材质:反射率、粗糙度(只影响成像灰度与对比度,不做全局光照)。
这样做的好处是真值是解析可得的:某个圆心在世界系里的坐标是一个精确值, 不是渲染出来再反推的近似值。真值评分能成立,靠的就是这一点。
针孔模型 + 畸变
世界点 p_W 到像素 (u, v) 的完整链路:
p_C = T_C_W · p_W 刚体变换到相机系
x = p_C.x / p_C.z, y = p_C.y / p_C.z 归一化平面
r² = x² + y²
x' = x(1 + k₁r² + k₂r⁴ + k₃r⁶) + 2p₁xy + p₂(r² + 2x²) 径向 + 切向畸变
y' = y(1 + k₁r² + k₂r⁴ + k₃r⁶) + p₁(r² + 2y²) + 2p₂xy
u = fx·x' + cx
v = fy·y' + cy
参数含义与常见量级:
| 参数 | 含义 | demo-2axis-vision 的取值 |
|---|---|---|
| fx, fy | 焦距(像素) | 7246.4, 7246.4(25 mm 镜头 / 3.45 µm 像元) |
| cx, cy | 主点 | 1224.0, 1024.0(略偏离几何中心是正常的) |
| k₁ | 一阶径向畸变 | −0.0214(桶形) |
| k₂ | 二阶径向畸变 | 0.0031 |
| p₁, p₂ | 切向畸变 | 1.2e−4, −0.8e−4(镜头与靶面不平行导致) |
fx ≠ fy 意味着像元不是正方形,工业相机上通常相等;如果你的标定结果里两者差了 1% 以上, 先怀疑标定板尺寸或数据,不要直接接受。
从连续到离散
图像不是「在圆心处采一个点」,而是对像元面积做积分:
I(u,v) = ∫∫_pixel L(x,y) · PSF(x,y) dx dy + noise
其中 PSF 是点扩散函数(见光学与离焦),
noise 见噪声模型。
实现上我们用超采样 + 面积加权近似这个积分(默认 4×4 子采样)。
这带来一个你应该知道的事实:圆心提取能达到亚像素精度,是因为边缘灰度是渐变的,
而渐变是积分的结果。如果把超采样关掉(supersample: 1),
圆心提取精度会立刻退化到 ±0.5 px——这也是真机上「曝光过度把边缘打死」时会发生的事。
灰度与曝光
DN = clamp( g · (Φ · t_exp · QE / e_full) · (2^bits − 1) + offset, 0, 2^bits − 1 )
| 符号 | 含义 |
|---|---|
| Φ | 到达像元的光通量(由材质反射率与光源强度决定) |
| t_exp | 曝光时间 |
| QE | 量子效率 |
| e_full | 满阱容量 |
| g | 增益(dB 转线性) |
过曝是硬截断,不是软压缩。这是有意的:真相机就是这样, 而过曝导致圆心偏移是标定里非常常见的误差来源,模型必须能复现它。
这个模型不做什么
诚实地列出来,免得你误以为它能验证这些:
- 不做全局光照:没有相互反射、没有阴影投射;
- 不做偏振与干涉;
- 不做真实镜头的色差(单色成像,工业相机多数如此);
- 不做传感器的行/列固定模式噪声(只做像素级噪声 + 坏点)。
需要验证上述现象的场合,虚拟设备给不了答案,必须上真机。
最后更新: 2026/9/21
这页有帮助吗?