基于LiDAR-相机变换矩阵绘制图像3D包围盒出错求助
针对你遇到的LiDAR坐标系3D包围盒投影到图像后位置偏差的问题,结合标定矩阵正确的前提,可从以下几个核心方向排查:
坐标系转换顺序与齐次坐标处理错误
确认外参的作用方向:若extrinsic_matrix是LiDAR到相机的变换矩阵,需将LiDAR点转换为齐次坐标([x,y,z,1])后再与矩阵相乘,得到相机坐标系下的点:lidar_point_homo = np.hstack((lidar_point, 1)) camera_point_homo = extrinsic_matrix @ lidar_point_homo camera_point = camera_point_homo[:3]相机到像素的转换需注意除以深度值(z轴),否则像素坐标会被深度缩放:
pixel_homo = intrinsic_matrix @ camera_point u, v = pixel_homo[0]/pixel_homo[2], pixel_homo[1]/pixel_homo[2]若跳过齐次坐标转换或深度归一化,会直接导致位置偏移。
欧拉角的旋转顺序与坐标系定义不匹配
不同数据集的欧拉角旋转顺序、坐标系轴向定义差异极大:- 例如KITTI数据集的欧拉角顺序为Z-Y-X(yaw绕Z轴,pitch绕Y轴,roll绕X轴),且LiDAR坐标系为X向前、Y向左、Z向上;
- Open3D的
get_rotation_matrix_from_euler默认旋转顺序为X-Y-Z,且默认坐标系为X向右、Y向前、Z向上。
需严格对齐标注文件中的欧拉角顺序与坐标系轴向,手动指定旋转参数:
# 若标注是Z-Y-X顺序,需明确指定 rot_mat = o3d.geometry.get_rotation_matrix_from_euler('zyx', [yaw, pitch, roll])同时需检查LiDAR与Open3D的坐标系差异,必要时对顶点进行轴向转换(如LiDAR的Y轴向左对应Open3D的X轴向左,需做坐标映射)。
3D包围盒顶点生成顺序错误
生成包围盒8个顶点的正确逻辑应为:- 生成单位立方体的原始顶点(如
[(-0.5,-0.5,-0.5), (0.5,-0.5,-0.5), ...]); - 对顶点进行缩放(乘以xyz尺度参数);
- 用旋转矩阵对缩放后的顶点进行旋转变换;
- 平移到包围盒的xyz位置。
若颠倒旋转与平移的顺序(先平移再旋转),会导致包围盒围绕原点旋转而非自身中心,引发位置偏移。
- 生成单位立方体的原始顶点(如
矩阵存储格式(行/列优先)不匹配
标定文件中的矩阵可能以行优先或列优先存储,需确认你读取矩阵的方式与官方实现一致。例如:- 若标定文件每行存储矩阵的一行,直接用
np.loadtxt读取即可; - 若文件存储的是列优先格式,需用
np.loadtxt(...).T转置后使用。
可直接打印你的extrinsic_matrix与官方实现的矩阵对比,确保数值完全一致。
- 若标定文件每行存储矩阵的一行,直接用
图像像素坐标系的轴向适配问题
图像像素坐标系通常以左上角为原点,u轴向右、v轴向下;而相机针孔模型的坐标系中Y轴可能向下或向上(取决于标定定义)。若标注的图像坐标系v轴向上,需将转换后的v坐标进行翻转:v = image_height - v未处理轴向差异会导致包围盒上下颠倒或垂直方向偏移。
Open3D可视化的坐标系对齐问题
若同时在Open3D中可视化LiDAR点云与投影的图像,需确保Open3D的相机内参与实际相机的intrinsic_matrix对齐,且可视化窗口的坐标系与LiDAR坐标系一致。若直接将LiDAR坐标系的包围盒导入Open3D但未做轴向转换,会导致显示视角偏差。
内容的提问来源于stack exchange,提问作者Muhammad Shahbaz

