相机外参与相机位姿深度明白
外参描述了相机活着界坐标系中的位置和朝向,即它将世界坐标转换为相机坐标的几何变动。详细来说,外参包罗一个 旋转矩阵 R R R 和一个 平移向量 t t t,它们共同构成了将世界坐标变动到相机坐标系的刚体变动。1. 外参矩阵的界说
外参矩阵通常体现为一个 3 × 4 3 \times 4 3×4 的矩阵,情势如下:
[ R t ] \begin{bmatrix} R & t \end{bmatrix}
其中:
[*] R R R 是一个 3 × 3 3 \times 3 3×3 的旋转矩阵,它描述了相机的朝向(姿态)。
[*] t t t 是一个 3 × 1 3 \times 1 3×1 的平移向量,它描述了相机相对于世界坐标系的平移。
该矩阵的作用是将世界坐标系下的点 P w = ( X w , Y w , Z w ) ⊤ \mathbf{P}_w = (X_w, Y_w, Z_w)^\top Pw=(Xw,Yw,Zw)⊤ 转换为相机坐标系下的点 P c = ( X c , Y c , Z c ) ⊤ \mathbf{P}_c = (X_c, Y_c, Z_c)^\top Pc=(Xc,Yc,Zc)⊤:
P c = R P w + t \mathbf{P}_c = R \mathbf{P}_w + t Pc=RPw+t
可以将这个过程写成齐次坐标情势,方便描述:
[ X c Y c Z c 1 ] = [ R t 0 1 ] [ X w Y w Z w 1 ] \begin{equation} \begin{bmatrix} X_c \\ Y_c \\ Z_c \\ 1 \end{bmatrix} = \begin{bmatrix} R & t \\ 0 & 1 \end{bmatrix} \begin{bmatrix} X_w \\ Y_w \\ Z_w \\ 1 \end{bmatrix} \end{equation} XcYcZc1 = XwYwZw1
这其中的 [ R t 0 1 ] \begin{bmatrix} R & t \\ 0 & 1 \end{bmatrix} 矩阵就是外参矩阵的扩展情势(齐次变动矩阵)。
2. 相机姿态推导
我们关心的是怎样从外参矩阵 [ R t ] \begin{bmatrix} R & t \end{bmatrix} 中推导出相机活着界坐标系中的姿态,即旋转和位置。
2.1 相机的位置
相机的世界坐标位置 C \mathbf{C} C 是通过将相机坐标原点逆变动到世界坐标系中得到的。相机坐标系中的原点在相机坐标下是 P c = ( 0 , 0 , 0 ) ⊤ \mathbf{P}_c = (0, 0, 0)^\top Pc=(0,0,0)⊤,因此有:
R C + t = 0 R \mathbf{C} + t = 0 RC+t=0
解得相机活着界坐标系中的位置为:
C = − R − 1 t \mathbf{C} = -R^{-1} t C=−R−1t
由于旋转矩阵 R R R 是正交矩阵,以是 R − 1 = R ⊤ R^{-1} = R^\top R−1=R⊤,因此相机位置可以体现为:
C = − R ⊤ t \mathbf{C} = -R^\top t C=−R⊤t
2.2 相机的朝向(姿态)
相机的姿态由旋转矩阵 R R R 体现,它将世界坐标系中的方向向量旋转到相机坐标系中。详细来说,旋转矩阵的列向量体现世界坐标系中基向量在相机坐标系中的方向。
因此, R R R 描述了相机相对于世界坐标系的旋转。假如想得到相机活着界坐标系中的姿态,可以求 R R R 的转置矩阵 R ⊤ R^\top R⊤,由于 R R R 将世界坐标系变动到相机坐标系,而 R ⊤ R^\top R⊤ 则是反向变动,即从相机坐标系变回世界坐标系的旋转。
3. 详细步骤总结
要从外参推导相机活着界坐标系中的姿态,步骤如下:
[*] 提取旋转矩阵 R R R:从外参矩阵 P = [ R t ] P = \begin{bmatrix} R & t \end{bmatrix} P= 中提取前 3 × 3 3 \times 3 3×3 的部门 R R R,这就是旋转矩阵,体现相机的朝向。
[*] 提取平移向量 t t t:从外参矩阵提取最后的 3 × 1 3 \times 1 3×1 部门 t t t,体现相机的平移。
[*] 盘算相机位置 C \mathbf{C} C:通过公式 C = − R ⊤ t \mathbf{C} = -R^\top t C=−R⊤t 得到相机的世界坐标系中的位置。
[*] 相机的朝向:旋转矩阵 R R R 直接描述了世界坐标系怎样转换到相机坐标系。假如需要相机活着界坐标系中的姿态(即从相机坐标系转换到世界坐标系),利用 R ⊤ R^\top R⊤ 作为反向旋转矩阵。
4. 示例
把前后左右四个相机用opencv viz模块绘制出来。
TEST(Demo, DemoOfCamera)
{
Sentinel_Config sentinel_config = GetDefaultConfig();
Camera2World front_camera2world(sentinel_config.front_yaml_path);
Camera2World rear_camera2world(sentinel_config.rear_yaml_path);
Camera2World left_camera2world(sentinel_config.left_yaml_path);
Camera2World right_camera2world(sentinel_config.right_yaml_path);
// visualize camera
cv::viz::Viz3d window("Coordinate Frame");
auto visualize_function = [&](Camera2World &camera2world, std::string widget_name)
{
cv::Matx33d K = camera2world.camera_param.para_K;
cv::Matx33d R = camera2world.camera_param.Rcw;
cv::Vec3d T = camera2world.camera_param.Tcw;
cv::Vec3d camera_position = -R.t() * T;
cv::viz::WCameraPosition cam(0.5); // Coordinate axes
cv::viz::WCameraPosition cam_frustum(K, 0.5, cv::viz::Color::green()); // Camera frustum
window.showWidget(widget_name, cam);
window.showWidget(widget_name+" frustum", cam_frustum);
// set the viewer pose
cv::Affine3d cam_pose(R.t(), camera_position);
window.setWidgetPose(widget_name, cam_pose);
window.setWidgetPose(widget_name+" frustum", cam_pose);
};
visualize_function(front_camera2world, "Front Camera");
visualize_function(rear_camera2world, "Rear Camera");
visualize_function(left_camera2world, "Left Camera");
visualize_function(right_camera2world, "Right Camera");
// visualize world
cv::viz::WCoordinateSystem world_coor(1.0);
window.showWidget("World", world_coor);
window.spin();
}
https://i-blog.csdnimg.cn/direct/728ff57fb5744c55961b1ade72015143.png
camera_position
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]