【点云处理】图达通激光点云数据转换

    刚刚拿到一批图达通雷达的激光点云数据的rosbag,准备拿去做3D目标的标注。播出来看了一眼,发现点云的坐标轴的设定与我们平常使用的坐标轴设定还不太一样。下图(1)是我直接通过rviz看到的点云图像,这样看你很难看出来是个什么东西。真实的图像应该是图(2)的样子,这样路面和山坡就看的比较清晰了。

【点云处理】图达通激光点云数据转换_第1张图片

图1

【点云处理】图达通激光点云数据转换_第2张图片

图(2)

好了,现在就是要做一个坐标转换,转换到我们熟悉的坐标轴定义下。

【点云处理】图达通激光点云数据转换_第3张图片

【代码】

#include 
#include 
//msgs type and conversion
#include 
#include 
#include 
#include 
#include 
#include 
#include 

ros::Publisher pub;
void call_back(const sensor_msgs::PointCloud2::ConstPtr input) {
    static int ch = 0;
    int point_bytes = input->point_step; //每个点的字节长度
    //点云数据以字节顺序存储在data容器中,offset是指在data中每个数据域的偏移
    int offset_x,offset_y,offset_z,offset_intensity;

    const auto& fields = input->fields;
    for (int f = 0; f < fields.size(); ++f) {
        if (fields[f].name == "x") offset_x = fields[f].offset;
        if (fields[f].name == "y") offset_y = fields[f].offset;
        if (fields[f].name == "z") offset_z = fields[f].offset;
        if (fields[f].name == "intensity") offset_intensity = fields[f].offset;
    }

    pcl::PointCloud cloud;//定义转换的点云数据类型
    for (int i=0; iwidth; ++i) {
        pcl::PointXYZI point;
        point.x = *(float*)(&input->data[0] + point_bytes*i + offset_x);
        point.y = *(float*)(&input->data[0] + point_bytes*i + offset_y);
        point.z = *(float*)(&input->data[0] + point_bytes*i + offset_z);
        point.intensity = *(unsigned char*)(&input->data[0] + point_bytes*i + offset_intensity);

        //坐标轴的转换
        auto tmp = point.x;
        point.x = point.z;
        point.y = -point.y;
        point.z = tmp;

        cloud.push_back(point);
    }
    cloud.width = input->width;
    cloud.height = input->height;

    if (1) {
        //发布转换后的点云
        sensor_msgs::PointCloud2 msg_publish;
        pcl::toROSMsg(cloud, msg_publish);
        msg_publish.header.frame_id = "innovusion";
        pub.publish(msg_publish);
    }
}


int main(int argc,char** argv) {
    // Initialize ROS
    ros::init (argc, argv, "pcl2pcd");
    ros::NodeHandle nh;

    // Create publish
    pub = nh.advertise("iv_points2_convert",1);
    // Create a ROS subscriber for the input point cloud
    ros::Subscriber sub = nh.subscribe ("iv_points2", 1, call_back);

    // Spin
    ros::spin ();
}

这里我设计了一个节点,订阅从rosbag中发布出来的图达通激光雷达的点云数据,然后借助pcl纠正了点云的坐标,再重新发布出去。我们再看转换后的点云图像(图3)就正常了。

【点云处理】图达通激光点云数据转换_第4张图片

图3

你可能感兴趣的:(点云处理,ros,点云,坐标转换,ros)