PCL点云 CSV格式转 PLY格式

大家好,我是青空。

最近在做项目的时候,遇到了需要把CSV 转换成点云文件的情况,主要是为了从csv 转换成的点云文件和从深度图转换成的点云文件做一个对比校验作用。

CSV 文件大致如下,本文的CSV 文件是由 基恩士激光传感器采集所的。大家如果是其他的传感器所得的数据,可能对应的关系有所不同的。
在这里插入图片描述
表格中行表示X轴方向的点,列表示Y轴方向的点,表格中的数值表示Z轴深度值。
每一个X与Y的间距是由传感器本身的精度和伺服电机的步长决定的。

#include <iostream>
#include <fstream>
#include <string>

#include<pcl/common/common.h>
#include <pcl/io/ply_io.h>

#include <opencv2/opencv.hpp>

//typedef pcl::PointXYZRGB point_t;
typedef pcl::PointXYZ point_t;
typedef pcl::PointCloud<point_t> pointcloud_t;


int endWith(std::string str, std::string sub) {
    return str.rfind(sub) == (str.length() - sub.length()) ? 1:0;
}

int main(int argc, char** argv) {

    std::string readFile = argv[1];

    std::cout << "readFile= " << readFile << std::endl;
    if (endWith(readFile, ".csv") == 0) {
        std::cout << "please input .csv file" << std::endl;
        system("pause");
        return 0;
    }
    
    std::ifstream csvfs(readFile, std::ios::binary | std::ios::in);
    
    std::string lineStr;
    std::string str;
    
    int yStep = 0;
    
    pointcloud_t::Ptr cloud(new pointcloud_t);
    point_t point;
    
    cv::Mat csvMat(3200, 3200, CV_32FC1);
    
    while (std::getline(csvfs, lineStr)) {
        std::stringstream ss(lineStr);
        int xStep = 0;
        while (std::getline(ss, str, ',')) {
            csvMat.at<float>(yStep, xStep) = std::stof(str);
            xStep++;
        }
        yStep++;
    }
    std::cout << "row= " << yStep << std::endl;
    
    auto row = csvMat.rows > yStep ? yStep : csvMat.rows;
    
    for (int r = 0; r < row; r++) {
        for (int c = 0; c < csvMat.cols; c++) {
            auto val = csvMat.at<float>(r, c);
            if (val < -50) {
                continue;
            }
            point.z = val / 1000;
            point.x = 0.01 * c / 1000;
            point.y = 0.01 * r / 1000;
            
            cloud->points.push_back(point);
        }
    }
    
    std::cout << "point cloud size = " << cloud->points.size() << std::endl;
    
    cloud->height = 1;
    cloud->width = cloud->points.size();
    pcl::io::savePLYFileBinary("cloudcsv.ply", *cloud);
    
    std::cout << "save point cloud ok, file name: cloudcsv.ply" << std::endl;
    system("pause");
    return 0;
}

PCL点云换为ROS点云格式需要进行以下步骤: 1. 创建一个ROS节点和发布者对象。 ```cpp ros::NodeHandle nh; ros::Publisher cloud_pub = nh.advertise<sensor_msgs::PointCloud2>("point_cloud", 1); ``` 2. 创建一个PCL点云对象和ROS点云对象。 ```cpp pcl::PointCloud<pcl::PointXYZ>::Ptr pcl_cloud(new pcl::PointCloud<pcl::PointXYZ>); sensor_msgs::PointCloud2 ros_cloud; ``` 3. 将PCL点云对象换为ROS点云对象。 ```cpp pcl::toROSMsg(*pcl_cloud, ros_cloud); ``` 4. 设置ROS点云对象的header信息。 ```cpp ros_cloud.header.frame_id = "base_link"; ros_cloud.header.stamp = ros::Time::now(); ``` 5. 发布ROS点云对象。 ```cpp cloud_pub.publish(ros_cloud); ``` 完整代码示例: ```cpp #include <ros/ros.h> #include <sensor_msgs/PointCloud2.h> #include <pcl_conversions/pcl_conversions.h> #include <pcl/point_cloud.h> #include <pcl/point_types.h> int main(int argc, char **argv) { // 初始化ROS节点 ros::init(argc, argv, "pcl_to_ros_publisher"); ros::NodeHandle nh; // 创建发布者对象 ros::Publisher cloud_pub = nh.advertise<sensor_msgs::PointCloud2>("point_cloud", 1); // 创建PCL点云对象 pcl::PointCloud<pcl::PointXYZ>::Ptr pcl_cloud(new pcl::PointCloud<pcl::PointXYZ>); // 填充PCL点云对象 // 将PCL点云对象换为ROS点云对象 sensor_msgs::PointCloud2 ros_cloud; pcl::toROSMsg(*pcl_cloud, ros_cloud); // 设置ROS点云对象的header信息 ros_cloud.header.frame_id = "base_link"; ros_cloud.header.stamp = ros::Time::now(); // 发布ROS点云对象 cloud_pub.publish(ros_cloud); // 循环等待 ros::spin(); return 0; } ```
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值