1. 1 问题描述
在利用2d图像进行相机位姿估计时需要进行实验验证,因此根据相机模型编写仿真代码,将3维空间点映射到最终的像素平面。
2. 2 相机模型
总体过程可以分位3部分:
- 将世界坐标系下的三维点用相机坐标系坐标表示
- 将相机坐标系下的点映射到成像平面,这个过程中深度信息丢失
- 将成像平面的点映射到像素坐标系,也就是最终相机拍摄到的照片上的像素坐标
2.1. 2.1 世界坐标系-相机坐标系
这是一个单纯的旋转平移过程
现在世界坐标系下平移$[T_x,T_y,T_z]$
$$
T\left(T_{x}, T_{y}, T_{z}\right)=\left[\begin{array}{cccc}
1 & 0 & 0 & T_{x} \
0 & 1 & 0 & T_{y} \
0 & 0 & 1 & T_{z} \
0 & 0 & 0 & 1
\end{array}\right]
$$先绕世界坐标系的x轴旋转$\alpha$
$$
\mathbf{R}_{x}(\alpha)=\left[\begin{array}{cccc}
1 & 0 & 0 & 0 \
0 & \cos \alpha & -\sin \alpha & 0 \
0 & \sin \alpha & \cos \alpha & 0 \
0 & 0 & 0 & 1
\end{array}\right]
$$再绕世界坐标系的y轴旋转$\beta$
$$
\mathbf{R}_{y}(\beta)=\left[\begin{array}{cccc}
\cos \beta & 0 & \sin \beta & 0 \
0 & 1 & 0 & 0 \
-\sin \beta & 0 & \cos \beta & 0 \
0 & 0 & 0 & 1
\end{array}\right]
$$最后绕世界坐标系的z轴旋转$\gamma$
$$
\mathbf{R}_{z}(\gamma)=\left[\begin{array}{cccc}
\cos \gamma & -\sin \gamma & 0 & 0 \
\sin \gamma & \cos \gamma & 0 & 0 \
0 & 0 & 1 & 0 \
0 & 0 & 0 & 1
\end{array}\right]
$$
因为是对坐标系的变换,因此按照顺序左乘各个矩阵可以描述为一个总体的变换矩阵
$$
T=T(T_x,T_y,T_z)R_z(\gamma)R_y(\beta)R_x(\alpha)
$$
假设$P_w:(X_w,Y_w,Z_w)$是世界坐标系下的坐标,$P_c:(X_c,Y_c,Z_c)$是相机坐标系下的坐标
则
$$
\begin{array}{}
P_1=TP_2 \
P_2=T^{-1}P_1
\end{array}
$$
2.2. 2.2 相机坐标系-成像平面坐标系
相机成像原理是在光在传感器上产生信号,也就是说实际上空间点和传感器上的位置是一一对应的。控制这个对应关系的变量是焦距$f$
根据相似三角形的几何特征,很容易可以得出
$$
\left{\begin{array}{l}
x=f \frac{X_c}{Z_c} \
y=f \frac{Y_c}{Z_c} \
z=f
\end{array}\right.
$$
其中$(X_2,Y_2,Z_2)$为相机坐标系中的坐标,$(x,y,z)$为成像平面坐标系中的坐标。为了和之前的齐次坐标相结合,这个变换也可以写成
$$
\left[\begin{array}{c}
x \
y \
z
\end{array}\right]=\left[\begin{array}{llll}
\frac{f}{Z_c} & 0 & 0 & 0 \
0 & \frac{f}{Z_c} & 0 & 0 \
0 & 0 & 1 & 0
\end{array}\right]\left[\begin{array}{c}
X_c \
Y_c \
Z_c \
1
\end{array}\right]
$$
2.3. 2.3 成像平面坐标系-像素坐标系
最后一步是转化到像素坐标系,也就是最终图像上的位置
上面推导中使用的像点坐标$(x,y)$是成像平面坐标系下,以成像平面的中心为原点。而实际像素点的表示方法是以像素来描述,坐标原点通常是图像的左上角,X轴沿着水平方向向左,Y轴竖直向下。像素是一个矩形块,这里假设其在水平和竖直方向的长度分别为:$\mu_x$和$\mu_y$。所以像素坐标和成像平面坐标之间,相差了一个缩放和原点的平移。
假设像素坐标的水平方向的轴为$u$,竖直方向的轴为$v$,那么将一个成像平面的坐标$(x,y)$在水平方向上缩放$\mu_x$倍,在竖直方向上缩放$\mu_y$倍,同时平移$(c_x,c_y)$,就可以得到像素坐标系的坐标$(u,v)$,其公式如下:
$$
\begin{array}{}
u=\frac{x}{\mu_x}+c_x \
v=\frac{y}{\mu_y}+c_y
\end{array}
$$
写成齐次坐标的形式为
$$
\left[\begin{array}{l}
\mu \
v \
1
\end{array}\right]=\left[\begin{array}{ccc}
\frac{1}{\mu_x} & 0 & c_{x} \
0 & \frac{1}{\mu_y} & c_{y} \
0 & 0 & 1
\end{array}\right]\left[\begin{array}{l}
x \
y \
1
\end{array}\right]
$$
2.4. 2.4 合并
将上述变换合成,可以得到
$$
Z_{c}\left[\begin{array}{l}
u \
v \
1
\end{array}\right]=\left[\begin{array}{ccc}
\frac{1}{\mu_x} & 0 & c_{x} \
0 & \frac{1}{\mu_ y} & c_{y} \
0 & 0 & 1
\end{array}\right]\left[\begin{array}{cccc}
f & 0 & 0 & 0 \
0 & f & 0 & 0 \
0 & 0 & 1 & 0
\end{array}\right]\left[\begin{array}{cc}
R & T \
\overrightarrow{0} & 1
\end{array}\right]\left[\begin{array}{c}
X_{w} \
Y_{w} \
Z_{w} \
1
\end{array}\right]
$$
3. 3 代码实现
1 | class VirtualCamera: |
4. 4 实验结果
在gazebo中进行仿真,将参数带入上述代码,进行对比,实验结果支持了模型的正确性
![一轴旋转,两方向位移情况](https://raw.githubusercontent.com/hujunhan/cloudimage/master/img/2021 06 17 15 16 42.png)
![两轴旋转,两方向位移情况](https://raw.githubusercontent.com/hujunhan/cloudimage/master/img/2021 06 17 15 17 01.png)