一、单应矩阵的引出
根据《16个相机参数》的推导,
zc⎣⎡uv1⎦⎤=K⋅[R0T1]⎣⎢⎢⎡xwywzw1⎦⎥⎥⎤=K⋅[r1r2r3T]⎣⎢⎢⎡xwywzw1⎦⎥⎥⎤
假设:标定棋盘位于世界坐标中zw=0平面,则
zc⎣⎡uv1⎦⎤=K⋅[r1r2r3T]⎣⎢⎢⎡xwyw01⎦⎥⎥⎤=K⋅[r1r2T]⎣⎡xwyw1⎦⎤
规定单应矩阵H为
H=K⋅[r1r2T]=⎣⎡fx000fy0u0v01⎦⎤[r1r2T]
则
zc⎣⎡uv1⎦⎤=H⎣⎡xwyw1⎦⎤
单应矩阵可用于图像校正、视角变换、图像拼接、相机位姿估计、视觉SLAM、增强现实等领域。
二、单应矩阵的计算
因为H是带有齐次坐标的3*3矩阵,所以H有8个未知解。所以可以进行任意尺度的缩放。
H=⎣⎡h11h21h31h12h22h32h13h23h33⎦⎤
即
zc⎣⎡uv1⎦⎤=⎣⎡h11h21h31h12h22h32h13h23h33⎦⎤⎣⎡xwyw1⎦⎤
上式展开得两个等式,则四个点,对应八个方程,可以计算出单应矩阵H。
计算8自由度H的方法:
- 1.直接设置h33=1
- 2.给H添加约束条件,令H的模=1
像素坐标{pixel}可以由相机获得,标定物的空间坐标{world}人为控制,是已知量。
三、相机标定过程:
利用打印的棋盘格子,对每个角点,标记其在{pixel}的像素坐标以及在{world}的空间坐标,计算得到H。
因为在真实的应用场景中,计算的点对中包含噪声,比如点额位置偏差几个像素,甚至出现特征点误匹配的现象。所以为了减少误差,增加鲁棒性,需要拍摄多张照片,选择大量角点进行标定。
此外,直接采用线性解法难以得到最优解,所以在实际使用中一般会用其他优化方法,比如奇异值分解、LM算法等进行求解。
相机标定的过程:
1、打印一张棋盘格标定图纸,贴在平面物体表面。
2、拍摄一组不同方向的棋盘格图片,可以移动相机实现,也可以移动标定图片实现
3、对于每张棋盘格图片,检测其中所有的棋盘格特征点(黑白格子交叉点,比如品红色的圈)。定义打印的图纸位于{world}的zw=0平面上,{world}的原点位于棋盘图纸的固定一角,比如图中黄色点。{pixel}原点位于图片左上角。
4、因为棋盘标定图纸中所有角点的空间坐标已知,其对应图片中的像素坐标已知,若得到4个以上匹配点,即可根据LM等优化方法计算得到单应矩阵H。

在opencv和c++中可直接输入匹配点对,指定具体计算方法得到输出结果。
参考资料
计算机视觉life公众号
https://www.cnblogs.com/zyly/p/9366080.html