(六)IO库教程二--PCD文件操作

PCD文件操作

本篇文章中会介绍对PCD文件的读写操作,点云的合并

操作类型

1. 读操作

头文件:
#include <pcl/io/pcd_io.h>

关键函数:从硬盘加载一个PCD格式的模板点云

template<typename PointT> inline int
    loadPCDFile (const std::string &file_name, pcl::PointCloud<PointT> &cloud)
  • 输入输出参数:
    • file_name[in]:选择加载的点云文件名
    • cloud[out]:加载了点云数据的模板点云.因为loadPCDFiles是一个模板函数,PointT表示加载的点云类型。当然这里可以改为之前章节中提到的所有点的类型。
    • 返回值[out]:int类型,0表示成功,-1代表加载失败
      举例:
pcl::io::loadPCDFile("Box.pcd", *pPointCloudIn);

2. 写操作

头文件:
#include <pcl/io/pcd_io.h>

关键函数:将一个模板点云保存为PCD格式文件写入硬盘

template<typename PointT> inline int
    savePCDFile (const std::string &file_name, const pcl::PointCloud<PointT> &cloud, bool binary_mode = false)
  • 输入输出参数:
    • file_name[in]:将要写入的文件名
    • cloud[in]:将要写的模板点云
    • binary_mode:PCD模式,默认是false表示是以ASCII码存储PCD文件,否则是以二进制模式存储。
    • 返回值[out]:int类型,0表示成功,-1代表存储失败
      举例:
pcl::io::savePCDFile("save.pcd", *pPointCloudIn);

3. 合并点云

合并点云分为两种类型:一是两个点云数据集的字段类型和维度相同,合并之后点云只是点的数量增加了;二是两个点云数据集的字段类型或维度不同,但是点的数量相同,合并之后相当于扩展了字段或维度,例如点云A是N个点的XYZ点集,点云B是N个点的RGB点,则连接两个字段形成的点云C是N个XYZRGB类型。

3.1 扩展点的数量

关键函数:扩展点云数量

inline const PointCloud
      operator + (const PointCloud& rhs)

举例:

cloud_c = cloud_a + cloud_b;
3.2 扩展点云字段或维数

关键函数:扩展点云字段或维数

template <typename PointIn1T, typename PointIn2T, typename PointOutT> void
pcl::concatenateFields (const pcl::PointCloud<PointIn1T> &cloud1_in,
                        const pcl::PointCloud<PointIn2T> &cloud2_in,
                        pcl::PointCloud<PointOutT> &cloud_out)


  • 输入输出参数:
    • cloud1_in[in]:合并的第一个点云
    • cloud2_in[in]:合并的第二个点云
    • cloud_out[out]:输出点云

一定要确定cloud1_in和cloud2_in点云数目相同,并且cloud_out的字段包含两个输入点云的所有字段。
举例:
// 一个PointXYZ类型的点云和一个Normal类型的点云合并为一个PointNormal类型点云
pcl::concatenateFields(cloud_c, cloud_normal, cloud_xyznormal);

程序

/*
 * 功能: I/O操作,包括PCD文件读写,点云合并
*/

#include <pcl/visualization/cloud_viewer.h>
#include <iostream>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>

int main()
{
    // 1. 扩展点云的点数
    pcl::PointCloud<pcl::PointXYZ> cloud_a, cloud_b, cloud_c;   // 保证合并的两个点云字段维数相同
    // 初始化点云
    cloud_a.width = cloud_b.width = 10;
    cloud_a.height = cloud_b.height = 1;                        // 无序点云,每个点云大小为10
    cloud_a.points.resize(cloud_a.width*cloud_a.height);
    cloud_b.points.resize(cloud_b.width*cloud_b.height);        // 不仅要初始化width,height而且还有points
    // 随机赋予点的XYZ值
    for (size_t i = 0; i < cloud_a.points.size(); ++i)
    {
        cloud_a.points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
        cloud_a.points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
        cloud_a.points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
    }
    for (size_t i = 0; i < cloud_b.points.size(); ++i)
    {
        cloud_b.points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
        cloud_b.points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
        cloud_b.points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
    }
    std::cerr << "Cloud A(size : " << cloud_a.size() << "):" << std::endl;
    for (size_t i = 0; i < cloud_a.points.size(); ++i)
        std::cerr << "    " << cloud_a.points[i].x << " " << cloud_a.points[i].y << " " << cloud_a.points[i].z << std::endl;
    std::cerr << "Cloud B(size : " << cloud_b.size() << "):" << std::endl;
    for (size_t i = 0; i < cloud_b.points.size(); ++i)
        std::cerr << "    " << cloud_b.points[i].x << " " << cloud_b.points[i].y << " " << cloud_b.points[i].z << std::endl;


    cloud_c = cloud_a + cloud_b;

    std::cerr << "Cloud C(size : " << cloud_c.size() << "):" << std::endl;
    for (size_t i = 0; i < cloud_c.points.size(); ++i)
        std::cerr << "    " << cloud_c.points[i].x << " " << cloud_c.points[i].y << " " << cloud_c.points[i].z << " " << std::endl;

    // 2. 扩展点云的字段或维数
    pcl::PointCloud<pcl::Normal> cloud_normal;
    pcl::PointCloud<pcl::PointNormal> cloud_xyznormal;
    cloud_normal.width = cloud_c.width;
    cloud_normal.height = cloud_c.height;
    cloud_normal.points.resize(cloud_normal.width*cloud_normal.height);
    cloud_xyznormal.width = cloud_c.width;
    cloud_xyznormal.height = cloud_c.height;
    cloud_xyznormal.points.resize(cloud_xyznormal.width*cloud_xyznormal.height);            // 保证两个点云数量相同
    for (size_t i = 0; i < cloud_normal.points.size(); ++i)
    {
        cloud_normal.points[i].normal[0] = 1024 * rand() / (RAND_MAX + 1.0f);
        cloud_normal.points[i].normal[1] = 1024 * rand() / (RAND_MAX + 1.0f);
        cloud_normal.points[i].normal[2] = 1024 * rand() / (RAND_MAX + 1.0f);
    }
    // 关键函数
    pcl::concatenateFields(cloud_c, cloud_normal, cloud_xyznormal);

    std::cerr << "Cloud RGB(size : " << cloud_normal.size() << "):" << std::endl;
    for (size_t i = 0; i < cloud_normal.points.size(); ++i)
        std::cerr << "    " << cloud_normal.points[i].normal_x << " " << cloud_normal.points[i].normal_y << " " << cloud_normal.points[i].normal_z << " " << std::endl;

    std::cerr << "Cloud XYZRGB(size : " << cloud_xyznormal.size() << "):" << std::endl;
    for (size_t i = 0; i < cloud_xyznormal.points.size(); ++i)
        std::cerr << "    " << cloud_xyznormal.points[i].x << " " << cloud_xyznormal.points[i].y << " " << cloud_xyznormal.points[i].z << "    " << cloud_xyznormal.points[i].normal_x << " " << cloud_xyznormal.points[i].normal_y << " " << cloud_xyznormal.points[i].normal_z << " " << std::endl;

    // 3. 保存PCD文件格式
    std::cout << "Save PCD!    " <<  pcl::io::savePCDFile("save.pcd", cloud_xyznormal) << std::endl;
    // 4. 读取PCD文件格式
    std::cout << "Load PCD!    " << pcl::io::loadPCDFile("save.pcd", cloud_xyznormal) << std::endl;

    std::system("pause");
    return 0;
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
7文件的程序,你可以按照以下步骤进行编写: 1. 引入PCL的头文件IO模块的头文件: ```c++ #include <iostream> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> ``` 2. 定义点云对象类型: ```c++ pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); ``` 3. 使用`pcl::io::loadPCDFile()`函数读取pcd文件: ```c++ if (pcl::io::loadPCDFile<pcl::PointXYZ>("example.pcd", *cloud) == -1) //* load the file { PCL_ERROR("Couldn't read file example.pcd \n"); return (-1); } ``` 4. 遍历点云对象并输出点的坐标: ```c++ for (size_t i = 0; i < cloud->points.size(); ++i) std::cout << " " << cloud->points[i].x << " " << cloud->points[i].y << " " << cloud->points[i].z << std::endl; ``` 完整代码示例: ```c++ #include <iostream> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> int main(int argc, char** argv) { pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); if (pcl::io::loadPCDFile<pcl::PointXYZ>("example.pcd", *cloud) == -1) //* load the file { PCL_ERROR("Couldn't read file example.pcd \n"); return (-1); } std::cout << "Loaded " << cloud->width * cloud->height << " data points from example.pcd with the following fields: " << std::endl; for (size_t i = 0; i < cloud->points.size(); ++i) std::cout << " " << cloud->points[i].x << " " << cloud->points[i].y << " " << cloud->points[i].z << std::endl; return (0); } ``` 你需要将代码中的 `example.pcd` 修改为你要读取的pcd文件名。运行程序后,它将输出点云中所有点的坐标。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值