【激光雷达-相机联合标定工具】lidar_camera_calibration

LiDAR-Camera Calibration using 3D-3D Point correspondences

简介

原项目来自LiDAR-Camera Calibration using 3D-3D Point correspondences,修改用于对相机和Robosense LiDAR联合标定。这里会简单写写标定步骤和我遇到的问题,我修改后的包已经放在了github上。

参考资料

其他依赖

标定步骤

camera_calibration

  1. 启动相机节点
  2. roslaunch capture_img run.launch 获取图片,使用MATLAB进行标定

lidar_camera_calibration

  1. create dir “/home/user/image_data/”
  2. 启动相机和激光雷达节点
    • roslaunch lidar_camera_calibration start_lidar_camera.launch
  3. 启动aruco节点,检查是否能识别到标志
    • roslaunch lidar_camera_calibration aruco.launch
  4. 启动标定节点
    • roslaunch lidar_camera_calibration calibration.launch

Attention

  1. 注意Aruco标志的方向,要和原项目中保持一致。

  2. sudo apt-get install ros-xxx-velodyne

  3. 将文件夹lidar_camera_calibration下的dependencies路径下的两个目录aruco_mapping和aruco_ros拷贝到ROS工作空间的src路径下,再进行编译。

  4. find_transform.launch启动ArUco mapping节点并修改其中的重映射命令使得获取正确的相机图片话题

    <remap from="/image_raw" to="xxx"/>

  5. 修改参数设置文件,主要是相机内参设置

  6. 注意一些文件被修改过(这里是因为我的两张ArUco图大小不一样,所以强行修改了源代码,如果两张图一样大小可以直接注释掉)

    1. aruco_mapping.cpp
    if(vis_marker.id == 26)
    {
        vis_marker.scale.x = 0.23;
        vis_marker.scale.y = 0.23;
    }
    else if(vis_marker.id == 582)
    {
        vis_marker.scale.x = 0.24;
        vis_marker.scale.y = 0.24;
    }
    else
    {
        vis_marker.scale.x = marker_size_;
        vis_marker.scale.y = marker_size_;
    }
    
    1. markerdetector.cpp
    if(detectedMarkers[i].id == 26)
    {
        //std::cout << "ID26" << std::endl;
        detectedMarkers[i].calculateExtrinsics ( 0.23,camMatrix,distCoeff,setYPerpendicular );
    }
    else if(detectedMarkers[i].id == 582)
    {
        //std::cout << "ID582" << std::endl;
        detectedMarkers[i].calculateExtrinsics ( 0.24,camMatrix,distCoeff,setYPerpendicular );
    }
    else
    {
        //std::cout << "wrong ID!!!!!!!!!!!!!!!!" << std::endl;
        detectedMarkers[i].calculateExtrinsics ( markerSizeMeters,camMatrix,distCoeff,setYPerpendicular );
    }
    
  7. 启动标定节点前,需要保证aruco标记能够在相机画面内可见。

  8. 注意PreprocessUtils.h的lidar线数设置

    std::vector <std::vector<myPointXYZRID *>> rings(16);

  9. 标定时注意如果是VNC远程连接工控机,需要外接键鼠直接标定,否则需要修改Corners.cpp代码。

    while (collected != 3*LINE_SEGMENTS[q]) {
    
        cv::setMouseCallback("cloud", onMouse, &_point_);
    
        cv::imshow("cloud", image_edge_laser);
        cv::waitKey(0);
        ++collected;
        std::cout << "collected:" << collected << std::endl;
        if(collected%3==1) //for VNC connect
            polygon.push_back(_point_);
    }
    

标定后使用

这个坑我也是翻了原项目的issue才发现怎么解决。
主要用到Final Rotation和Average translation作为[R|t],其中final_rotation = rotation_avg * lidarToCamera

### LiDAR 数据与相机图像的融合技术 在计算机视觉领域,LiDAR相机传感器的数据融合是一个重要的研究方向。通过将这两种不同类型的传感数据结合起来,可以显著提高环境感知的质量和准确性。 #### 融合方法概述 常见的融合方式有两种:早期融合(Early Fusion)和后期融合(Late Fusion)。早期融合适用于原始数据层面的操作,在获取到两种模态的数据之后立即进行处理;而后期融合则是在各自完成特征提取后再做关联分析[^1]。 对于 **LiDARCamera 的转换** ,主要涉及坐标系变换以及投影矩阵计算: - 首先定义世界坐标系下的点云位置; - 使用外参矩阵将这些三维空间中的点映射至二维平面即摄像头视角下; - 应用内参数校准后的摄像机模型进一步调整最终成像效果。 具体实现过程中会涉及到如下几个方面的工作: 1. 多传感器同步采集时间戳匹配; 2. 建立精确的空间几何关系描述两设备间相对位姿变化规律; 3. 设计合理的算法框架来解决遮挡等问题带来的挑战。 ```python import numpy as np def lidar_to_camera(lidar_points, extrinsic_matrix, intrinsic_matrix): """ Convert Lidar points into corresponding pixel coordinates on the camera image. Parameters: lidar_points (np.ndarray): N x 3 array representing X,Y,Z positions from LIDAR sensor. extrinsic_matrix (np.ndarray): 4x4 transformation matrix describing position & orientation between sensors. intrinsic_matrix (np.ndarray): 3x3 matrix containing focal length and principal point offsets. Returns: tuple: Two arrays of shape (N,) each holding u,v values which are column,row indices respectively within an image frame. """ # Transform lidar points to homogeneous coordinate system homog_lidar_pts = np.hstack((lidar_points, np.ones((len(lidar_points), 1)))) # Apply external parameters for global alignment then project onto local plane using internals cam_coords = intrinsic_matrix @ ((extrinsic_matrix[:3,:3]@homog_lidar_pts.T).T + extrinsic_matrix[:3,-1]) # Normalize by dividing z component so that we get normalized device coordinates before converting them back again via division with w=1 hereafter dropping last dimension since it should be all ones now anyway because this is just a projection operation afterall... ndc = cam_coords / cam_coords[:, -1][:, None] return ndc[:,:2].astype(int) ```
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值