无论是针孔相机还是鱼眼相机,其实可以归类成一个相机模型(畸变方式有差别而已),模型如下:
P ′ ( X Z , Y Z , 1 ) P^{'}(\frac{X}{Z},\frac{Y}{Z},1) P′(ZX,ZY,1) : P P P 投影在归一化平面上的点,坐标有三角形相似推出;
P ′ ′ ( X Z f , Y Z f , f ) P^{''}(\frac{X}{Z}f,\frac{Y}{Z}f,f) P′′(ZXf,ZYf,f) : P P P 投影在成像平面上的点,坐标有三角形相似推出;
P d ′ P_d^{'} Pd′ : P ′ P^{'} P′ 在镜头畸变后的点,d是distortion的缩写;
P d ′ ′ P_d^{''} Pd′′ : P ′ ′ P^{''} P′′ 在镜头畸变后的
需要说明的是,真实相机在物理上,相机成像平面和像素平面本来是再光心后的,但为了便于分析,通常将两个平面对称到图上位置,相机通常会在数字图像处理时会在X和Y轴方向对称处理下,因而下图这样的模型和现实坐标结果一致。
以上过程为理想过程,也就是最简单的针孔相机模型(下式中间矩阵就是内参矩阵 K K K):
[ u v 1 ] = 1 Z [ f x 0 C x 0 f y C y 0 0 1 ] [ X Y Z ] \begin{bmatrix} u\\ v\\1\end{bmatrix}=\frac{1}{Z}\begin{bmatrix} f_x & 0 & C_x\\ 0 & f_y & C_y\\ 0 & 0 &1\end{bmatrix} \begin{bmatrix} X\\ Y\\Z\end{bmatrix} ⎣⎡uv1⎦⎤=Z1⎣⎡fx000fy0CxCy1⎦⎤⎣⎡XYZ⎦⎤
然而现实是, P P P到 P ′ P^{'} P′时(也即光从镜头进入相机归一化平面时)会有镜头引起的畸变(具体畸变类型下面有讲),从而导致从 P ′ P^{'} P′变成了 P d ′ P^{'}_d Pd′, P d ′ P^{'}_d Pd′会继续按照之前的映射变成 P d ′ ′ P^{''}_d Pd′′,因而可以看出如何计算出从 P ′ P^{'} P′到 P d ′ P^{'}_d Pd′最重要,这个过程就是畸变模型。
畸变模型是相机模型中的一个子问题,请注意区分。
畸变模型分为两类,径向畸变和切向畸变:
径向畸变是,距离光心距离不同的点的畸变程度不一样
切向畸变,成像平面与小孔平面不平行引起侧倾
桶形失真就是距离图像中心越远,原来的光点就被拉向中心越多,枕形失真相反;
这里的 ( x n , y n ) (x_n,y_n) (xn,yn)就是 P ′ P^{'} P′的前两项, ( x d , y d ) (x_d,y_d) (xd,yd)就是 P ′ ′ P^{''} P′′的前两项,在归一化平面上Z坐标都为1;
畸变参数和相机内参都可以通过标定求得,得到畸变参数后,如何进行去畸变呢?
答:根据要求取的像素平面位置 u v uv uv,计算对应无畸变的归一化平面图像坐标 P ′ P^{'} P′,找到这个坐标在畸变模型下的位置 P d ′ P^{'}_d Pd′,进而找到相机模型下转移到当前畸变像素的位置 P d ′ ′ P^{''}_d Pd′′和 u v d uv_d uvd,然后取出来放到真实像素平面(找到 u v d uv_d uvd可能不是整数,会用到双线性插值)
在实际相机使用过程中,我们最大的需求是:建立像素坐标 u v uv uv和真实3D坐标 P P P的对应关系。
一般真实坐标并不是以相机坐标系为坐标系,而是在其他坐标系(如下图的世界坐标系,也可是其他传感器,如IMU等)下的坐标
R c w R_{cw} Rcw
X c = [ R c w T c w ] [ X w 1 ] X_c=\begin{bmatrix}R_{cw} & T_{cw}\end{bmatrix}\begin{bmatrix}X_w\\ 1\end{bmatrix} Xc=[RcwTcw][Xw1]
P ′ = [ X c ( 0 ) X c ( 2 ) X c ( 1 ) X c ( 2 ) 1 ] = [ x n y n 1 ] P^{'}=\begin{bmatrix}\frac{X_c(0)}{X_c(2)}\\ \frac{X_c(1)}{X_c(2)}\\ 1\end{bmatrix} = \begin{bmatrix}x_n \\ y_n\\ 1\end{bmatrix} P′=⎣⎢⎡Xc(2)Xc(0)Xc(2)Xc(1)1⎦⎥⎤=⎣⎡xnyn1⎦⎤
P d ′ = [ x d y d 1 ] P^{'}_d=\begin{bmatrix}x_d \\ y_d\\ 1\end{bmatrix} Pd′=⎣⎡xdyd1⎦⎤
内参转换:
( u v 1 ) = ( f x 0 C x 0 f y C y 0 0 1 ) [ x d y d 1 ] \begin{pmatrix}u\\ v\\ 1\end{pmatrix}=\begin{pmatrix}f_x & 0 & C_x\\ 0& f_y & C_y\\ 0&0 &1 \end{pmatrix}\begin{bmatrix}x_d \\ y_d\\ 1\end{bmatrix} ⎝⎛uv1⎠⎞=⎝⎛fx000fy0CxCy1⎠⎞⎣⎡xdyd1⎦⎤
注:标定时标定板应该尽量在图片四周,才能尽可能估计出准确的畸变参数。
相机标定之张正友标定法数学原理详解(含python源码)
图像处理–相机标定(Camera calibration)_fengye2two的专栏-CSDN博客_图像标定
摄像头标定 Python + OpenCV
图像矫正去畸变_雾里_看花的博客-CSDN博客
[图像]图像缩放算法-双线性内插法_祥的专栏-CSDN博客
Camera Calibration Theory - Calcam documentation
鱼眼相机成像模型_sylvester的博客-CSDN博客_鱼眼相机模型