返回

相机镜头在陀螺仪IMU坐标系的位置转换方法

Android

求解:相机镜头在陀螺仪/IMU坐标系中的位置

通常,设备姿态估计需要融合来自陀螺仪(IMU)的角速度信息以及其他传感器数据。 在进行相机和IMU数据融合时,精确确定相机镜头相对于陀螺仪坐标系的位姿变得至关重要。 有时,系统提供的默认镜头姿态参考不满足特定需求。例如,当应用需要镜头在陀螺仪坐标系中的姿态时,如果系统只提供镜头相对于主摄像头的参考,便需要额外的转换步骤。本文将探讨一些解决这一问题的策略。

问题剖析

Camera2 API 以及 ARCore 提供便捷的相机访问及 AR 增强功能,但设备在某些情况下会返回 LENS_POSE_REFERENCE_PRIMARY_CAMERA,这指示镜头位置是相对于主摄像头参考的。我们期望获取相对于陀螺仪(或IMU)坐标系的镜头位置,以此用于精密的姿态估计或相机与 IMU 数据的同步。 这表明系统默认配置无法满足需求,因此需要自定义解决方案。问题核心是如何建立主摄像头坐标系和陀螺仪坐标系之间的变换关系。

解决方案一:基于姿态的转换

原理: 这种方法基于同时获取设备的姿态信息(通常表示为一个旋转矩阵或四元数),姿态信息基于 IMU, 并且利用 CameraCharacteristics 获取相机镜头在主摄像头参考坐标系的位置。 通过对姿态信息的转换,便能将镜头位置转换到陀螺仪坐标系。

步骤:

  1. 获取姿态: 使用诸如 Android RotationVectorSensor 或者 ARCore 提供的姿态跟踪功能,获取设备在全局或IMU坐标系下的姿态,这可以用旋转矩阵或四元数表示。
  2. 获取 CameraCharacteristics: 使用 Camera2 API, 获取相机的特性, 特别是 LENS_POSE_TRANSLATION (镜头平移向量), LENS_POSE_ROTATION(镜头旋转矩阵)。 这两项数据定义了镜头相对于主摄像头参考坐标系的位置。
  3. 转换: 如果步骤 1 中的姿态矩阵(表示设备在IMU坐标系中的旋转)用 R_imu 表示, 从主摄像头坐标系到 IMU 坐标系的旋转关系用 R_camera_imu表示, 主摄像头到 IMU 的平移关系 T_camera_imu, 则可以用如下公式计算镜头在IMU坐标系的位置: P_imu = R_camera_imu * R_lens + R_camera_imu * T_lens + T_camera_imu, 这里 P_imu 是镜头在IMU坐标系下的位置,R_lens 为镜头相对于主摄的旋转,T_lens 为镜头相对于主摄的平移。 注意如果步骤 1 获取的是四元数,需要将其转换为旋转矩阵进行计算。
    R_camera_imuT_camera_imu 可能需要一个小的离线标定过程。
    一般情况可以近似的用恒等旋转矩阵, 并设置平移为零, 即 R_camera_imu = I, T_camera_imu = 0.
  4. 更新: 当陀螺仪数据发生变化(即,设备姿态改变), 更新姿态矩阵,并重新进行上述变换。

代码示例(伪代码):

# 获取 IMU 姿态 (旋转矩阵)
imu_rotation = get_imu_rotation() 
# 获取相机特性 (镜头平移,旋转)
camera_translation = get_camera_lens_translation() # 矢量
camera_rotation = get_camera_lens_rotation()   # 旋转矩阵

# 简化假设相机和 IMU 在空间上对齐, 实际应用中可以考虑一个额外的标定过程
camera_imu_rotation = identity_matrix()
camera_imu_translation = [0, 0, 0]

# 计算镜头在IMU坐标系的位置
camera_translation_imu  =   np.dot(camera_imu_rotation,camera_rotation.transpose()) \
                    +   np.dot(camera_imu_rotation, camera_translation ) +   camera_imu_translation

# 后续操作

操作步骤:

  1. 获取可用的IMU数据接口, 获取姿态旋转信息。
  2. 获取摄像头句柄和相应CameraCharacteristics.
  3. 实现上述的矩阵运算, 获取对应时间戳下镜头的位姿。
  4. 根据新的陀螺仪数据, 重新计算镜头位姿。

解决方案二:基于外参标定

原理: 如果在设计阶段已经了解相机模块与IMU传感器在设备中的物理布局(通常需要设备厂商的详细文档), 这种方式可以利用相机和IMU之间的已知静态变换, 将镜头位置从相机参考坐标系转换到IMU坐标系。这种变换是静态的, 因此标定一次就可以重复使用。

步骤:

  1. 标定参数获取: 获取相机镜头坐标系相对于 IMU 坐标系的静态转换参数,这包括一个旋转矩阵( R_calibrated )和一个平移向量 (T_calibrated)。 通常情况下这需要使用特定标定工具或者依赖厂商提供的信息。
  2. 获取 CameraCharacteristics 使用 Camera2 API, 读取 LENS_POSE_TRANSLATIONLENS_POSE_ROTATION. 这两个数据代表相机镜头在主摄参考下的平移和旋转信息。
  3. 转换: 如果相机镜头在主摄坐标系的位置由平移向量 T_lens 和 旋转矩阵 R_lens 表示, 则镜头在 IMU 坐标系的位置可以使用 P_imu = R_calibrated * R_lens + R_calibrated * T_lens + T_calibrated 计算得到.
  4. 重复使用: 在设备上只要这个布局不变, 这种关系是保持静态不变的, 可以直接应用。

命令行指令/代码示例:

# 假设经过标定过程已经得到了静态旋转矩阵和转换矩阵
R_calibrated =  get_static_calibration_rotation()  # 读取已标定旋转矩阵
T_calibrated =  get_static_calibration_translation() # 读取已标定平移向量

#获取相机特性 
camera_translation = get_camera_lens_translation()
camera_rotation = get_camera_lens_rotation()

camera_translation_imu  =   np.dot(R_calibrated ,camera_rotation.transpose()) \
                     +  np.dot(R_calibrated, camera_translation) +   T_calibrated
# 后续操作

操作步骤:

  1. 使用厂商提供的或者特定标定程序获取相机镜头相对于IMU传感器的静态外参(即, R_calibratedT_calibrated ) 。
  2. 利用 Camera2 API获取相机的内部镜头数据。
  3. 应用计算公式, 得到镜头在 IMU坐标系的姿态.
  4. 重复利用该转换关系, 直接应用到每一帧数据中。

安全提示

进行坐标转换时,务必确保数据类型的正确性,旋转矩阵的顺序和定义应保持一致。 当使用传感器原始数据时, 需要考虑设备及系统的校准情况, 例如是否有偏置误差。 使用外部标定数据的时候应该使用严格的单位标准,并确保参数来自可靠来源。 当依赖在线标定时, 需要引入校验机制, 以防止出现计算错误。