PCL学习笔记1-整体框架

PCL是一个模块化的C++模板库, 实现点云相关的获取、滤波、分割、配准、检索、特征提取、识别、追踪、曲面重建、可视化等。

要学习的正是PCL中的16个模块

 各模块之间的依赖关系如图所示。

PCL可用于机器人领域、逆向工程、激光遥感测量、虚拟现实和人际交互等。

在PCL中一个处理管道的基本接口程序如下:

1. 创建处理对象

2. 使用setInputCloud通过输入点云数据,处理模块

3. 设置算法相关参数

4. 调用计算(过滤、分割)得到输出

(管道本质上就是一个文件,前面的进程以写方式打开文件,后面的进程以读方式打开)

学习各个模块可以参考其他大佬的中文博客,结合代码体会学习。

# .PCD v.7 - Point Cloud Data file format
VERSION .7								# 版本号
FIELDS x y z rgb				#  指定一个点可以有的每一个维度和字段的名字
SIZE 4 4 4 4								# 用字节数指定每一个维度的大小。例如:
TYPE F FFF									# 用一个字符指定每一个维度的类型 int uint folat
COUNT 1 1 1 1						# 指定每一个维度包含的元素数目
WIDTH 640    						   # 像图像一样的有序结构,有640行和480列,
HEIGHT 480    					  # 这样该数据集中共有640*480=307200个点
VIEWPOINT 0 0 0 1 0 0 0			# 指定数据集中点云的获取视点 视点信息被指定为平移(txtytz)+四元数(qwqxqyqz)
POINTS 307200						# 指定点云中点的总数。从0.7版本开始,该字段就有点多余了
DATA ascii										# 指定存储点云数据的数据类型。支持两种数据类型:ascii和二进制
0.93773 0.33763 0 4.2108e+06
0.90805 0.35641 0 4.2108e+06

PCD文件头必须用ASCII码来编码

·TYPE –用一个字符指定每一个维度的类型。现在被接受的类型有:

I –表示有符号类型int8(char)、int16(short)和int32(int);

U – 表示无符号类型uint8(unsigned char)、uint16(unsigned short)和uint32(unsigned int);

F –表示浮点类型。

WIDTH –用点的数量表示点云数据集的宽度

1)确定无序数据集的点云中点的个数;

2)确定有序点云数据集的宽度(一行中点的数目)。

·HEIGHT –用点的数目表示点云数据集的高度。

1)有序点云数据集的高度(行的总数);

2)无序数据集它被设置成1。

·DATA –指定存储点云数据的数据类型。从0.7版本开始,支持两种数据类型:ascii和二进制。

​​​​​​点云文件常用格式转换(pcd,txt,ply,obj,stl)_给算法爸爸上香的博客-CSDN博客_pcd转obj

在PCL中定义了大量的point类型,在以下文件中

common/include/pcl/impl/point_types.hpp

sensor_msgs::PointCloud2(ROS点云数据) 转成PointXYZI(PointT)

void elevatedCloudCallback(const  sensor_msgs::PointCloud2::ConstPtr & input_cloud)  // PointCloud2
{
    // 将接收到的消息打印出来
    // ROS_INFO(  input_cloud->header);
    pcl::PointCloud<PointT>::Ptr output_cloud(new pcl::PointCloud<PointT>());   // input_cloud转换成pcl数据类型laser_cloud
    pcl::fromROSMsg(*input_cloud, *output_cloud);//转换成pcl数据类型
    std::cout <<output_cloud->header<< std::endl;
    std::cout << output_cloud->points[1].x<< std::endl;
}

将点云类型pcl::PointXYZI转换成pcl::PointXYZ

  pcl::PointCloud<pcl::PointXYZI>::Ptr keypoints (new pcl::PointCloud<pcl::PointXYZI>);
  keypoints_Harris( cloud_xyz, keypoints);

  pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints_ptr(new pcl::PointCloud<pcl::PointXYZ>); 
  copyPointCloud (*keypoints , *keypoints_ptr);

实现类似pcl::PointCloud::Ptr和pcl::PointCloud的两个类相互转换

#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
 
pcl::PointCloud<pcl::PointXYZ>::Ptr cloudPtr(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ> cloud;
cloud = *cloudPtr;//由Ptr转变为另一种类型
cloudPtr = cloud.makeShared();//转变为Ptr类型

cloudPtr原本是一个指针,取值后就是PointCloud类型

将xyzrgb格式转换为xyz格式的点云

typedef是给某类取新名字

#include <pcl/io/pcd_io.h>
#include <ctime>
#include <Eigen/Core>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
using namespace std;
typedef pcl::PointXYZ point;
typedef pcl::PointXYZRGBA pointcolor;
int main(int argc,char **argv)
{
        pcl::PointCloud<pointcolor>::Ptr input (new pcl::PointCloud<pointcolor>);
        pcl::io::loadPCDFile(argv[1],*input);
        
        pcl::PointCloud<point>::Ptr output (new pcl::PointCloud<point>);
        int M = input->points.size();
        cout<<"input size is:"<<M<<endl;
        for (int i = 0;i <M;i++)
        {
                point p;
                p.x = input->points[i].x;
                p.y = input->points[i].y;
                p.z = input->points[i].z; 
                output->points.push_back(p);
        }
        output->width = 1;
        output->height = M;
        
        cout<< "size is"<<output->size()<<endl;
        pcl::io::savePCDFile("output.pcd",*output);
}

Point已经定义好了很多类型,根据需要再去查阅即可。

猜你喜欢

转载自blog.csdn.net/luoyihao123456/article/details/125242424