双目标定原理

为什么需要进行双目标定?

双目测距中有一个常用公式:

Z = f * B / d

其中:

Z:深度
f:焦距
B:双目基线
d:视差

这个公式建立在理想平行双目模型上,也就是:

左右相机光轴平行
左右成像平面共面
对应点位于同一行

但实际安装时,两台相机之间一定存在旋转和平移。

所以双目标定的目的就是:

求出左右相机之间真实的旋转关系 R 和平移关系 T,再利用它们把左右图像校正成理想平行双目。


一、双目标定到底求什么

左右相机先分别完成单目标定,得到:

左相机:KL、DL
右相机:KR、DR

其中:

K:相机内参
D:畸变参数

双目标定主要计算:

R
T

使同一个空间点满足:

PR = R * PL + T

其中:

PL:点在左相机坐标系中的坐标
PR:点在右相机坐标系中的坐标

所以可以简单理解为:

内参标定:
相机自己是什么样

双目标定:
两个相机之间怎么摆

二、为什么要同时拍标定板

双目标定时,让左右相机同时看到同一块标定板。

假设标定板上的一个角点为:

Pw = (Xw, Yw, 0)

左相机检测到:

pL = (uL, vL)

右相机检测到:

pR = (uR, vR)

于是就建立了:

同一个真实空间点 Pw
        ↓
左图像素 pL
        ↓
右图像素 pR

一张标定板上有很多角点,拍很多组不同姿态的标定板,就能得到大量这样的对应关系。


三、R和T是怎么来的

对于同一张标定板:

PL = RL * Pw + TL
PR = RR * Pw + TR

从左相机公式得到:

Pw = RL^-1 * (PL - TL)

旋转矩阵满足:

RL^-1 = RL^T

所以:

Pw = RL^T * (PL - TL)

代入右相机:

PR = RR * RL^T * (PL - TL) + TR

展开:

PR
=
RR * RL^T * PL
-
RR * RL^T * TL
+
TR

和:

PR = R * PL + T

比较得到:

R = RR * RL^T
T = TR - R * TL

也就是说,同一块标定板同时被两个相机看到后,就可以通过:

标定板 -> 左相机
标定板 -> 右相机

的关系,推出:

左相机 -> 右相机

的 R、T。


四、为什么要拍很多张图片

理论上一组姿态就可以算出一次 R、T,但实际角点位置存在:

角点检测误差
图像噪声
畸变模型误差
标定板制造误差

所以单组图片算出的 R、T 会有偏差。

实际会拍很多组:

第1组:左图1 + 右图1
第2组:左图2 + 右图2
第3组:左图3 + 右图3
...

然后不是把每组算出的 R、T 简单求平均,而是:

让所有图片中的所有角点共同约束同一组固定的 R、T。

假设当前参数预测某个角点应该出现在:

左图:pL'
右图:pR'

实际检测结果是:

左图:pL
右图:pR

那么误差就是:

eL = pL - pL'
eR = pR - pR'

优化器不断调整参数,使所有图片、所有角点的总体误差:

Σ ||pL - pL'||²
+
Σ ||pR - pR'||²

尽可能小。

所以多拍图片的本质就是:

大量不同姿态的数据
        ↓
共同约束同一个R、T
        ↓
降低单张图片随机误差的影响
        ↓
得到更加稳定的R、T

工程中通常先分别标定好两个相机的内参,然后双目标定时固定:

KL
KR
DL
DR

只优化:

R
T

OpenCV中常使用:

CALIB_FIX_INTRINSIC

五、T和基线B是什么关系

例如双目标定得到:

T = (-120, 0.5, 1.2)mm

说明两个相机光心之间主要相差约 120 mm。

双目基线就是两个相机光心之间的距离:

B = ||T||

也就是:

B = sqrt(Tx² + Ty² + Tz²)

这个 B 就是:

Z = f * B / d

中的基线。


六、双目标定后为什么还要双目校正

虽然已经知道了 R、T,但原始左右相机仍然可能是:

左相机              右相机

   ↑ZL                ↗ZR
   |                 /
   O --------------- O

所以同一个空间点可能出现在:

左图:(800, 420)
右图:(650, 416)

此时:

vL != vR

说明对应点既有横向差,也有纵向差,不方便做匹配。

因此需要根据 R、T 对左右图像进行双目校正。

校正后得到两个新的虚拟相机:

校正后左相机        校正后右相机

     ↑Z                  ↑Z
     |                   |
     O ----------------- O
              B

使得:

成像平面共面
光轴平行
极线水平

最终同一个空间点满足:

左图:(uL, v)
右图:(uR, v)

也就是:

vL ≈ vR

OpenCV进行双目校正后通常得到:

R1
R2
P1
P2
Q

其中:

R1、R2:左右相机校正旋转
P1、P2:校正后的投影矩阵
Q:视差转3D矩阵

七、极线、E和F是什么

左图确定一个点 pL 后,它在右图中的对应点并不是任意位置,而一定落在一条特定的线上,这条线叫:

极线。

所以双目匹配本来是:

左图一个点
↓
去右图的一条极线上寻找对应点

双目校正以后,极线被变成水平线,因此:

左图第400行
↓
只需要搜索右图第400行

极线约束可以写成:

xR^T * E * xL = 0

其中:

E = [T]x * R

E 是本质矩阵,描述归一化相机坐标下的极线关系,本质上由 R、T 决定。

如果直接使用像素坐标:

pR^T * F * pL = 0

其中:

F = KR^-T * E * KL^-1

所以简单记:

E:R、T对应的极线约束

F:加入左右相机内参后的像素极线约束

八、双目是怎么得到3D的

双目校正以后,同一个空间点为:

左图:(uL, v)
右图:(uR, v)

视差:

d = uL - uR

对于理想平行双目:

Z = f * B / d

得到深度以后:

X = (uL - Cx) * Z / fx
Y = (v - Cy) * Z / fy

最终得到三维坐标:

P = (X, Y, Z)

因为:

d = f * B / Z

所以:

物体越近 -> Z越小 -> 视差越大
物体越远 -> Z越大 -> 视差越小

因此不同深度的空间点,视差通常不同。

OpenCV中的 Q 矩阵已经组合了焦距、主点和基线等关系,可以直接实现:

(u, v, d)
    ↓
    Q
    ↓
(X, Y, Z)

例如:

reprojectImageTo3D

就是利用这个关系把视差图转换成点云。


九、怎么判断双目标定好不好

双目标定不能只看程序有没有成功,还要看最终三维效果。

主要检查:

1. 重投影误差是否足够小

2. 校正后左右对应点行差:
   |vL - vR|
   是否接近0

3. 校正后的极线是否水平

4. 拍摄真实平面,看点云是否:
   弯曲
   波浪
   重影
   变形

5. 测量已知距离,看3D误差

例如真实距离:

500 mm

重建结果:

503 mm

那么深度误差就是:

3 mm

重投影误差反映的是:

当前数学模型是否能够解释标定图片。

而真实平面和已知距离测试反映的是:

最终三维重建到底准不准。

所以二者都需要检查。


十、完整双目标定流程

左相机单目标定
        ↓
得到KL、DL

右相机单目标定
        ↓
得到KR、DR

左右相机同时拍摄多组标定板
        ↓
检测左右角点
        ↓
大量3D角点与左右2D像素建立对应
        ↓
优化得到左右相机R、T
        ↓
根据R、T进行Stereo Rectify
        ↓
得到R1、R2、P1、P2、Q
        ↓
左右图去畸变 + 校正
        ↓
对应点基本同行
        ↓
计算视差d
        ↓
Z = fB/d
        ↓
得到X、Y、Z
        ↓
生成3D点云

所以整个双目系统最核心的关系可以浓缩成:

单目标定
↓
知道每个相机自己怎么成像

双目标定
↓
知道两个相机之间怎么摆

双目校正
↓
把两个相机变成理想平行双目

左右匹配
↓
得到视差d

Z = fB/d
↓
得到三维坐标

一句话理解双目标定:

双目标定就是让左右相机同时观察大量相同的空间点,通过这些点在左右图像中的位置,共同优化出两个相机坐标系之间固定的旋转 R 和平移 T,再利用它们完成图像校正和三维重建。

最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容