携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情
PointT类型
PCL的PointT类型可以追溯到它在ROS作为开源库被开发的时候,大家一致认为,点云是复杂的n维度结构,它应该能够传递不同类型的信息,然而用户应该知道并且理解需要传送什么信息,然而用户应该知道并且理解需要传送什么样的信息,从而使代码更加易于调试和优化等。下面给出一个例子,是对XYZ数据的简单操作。对带有SSE功能的处理器,最高效的方法就是存储三维坐标为浮点数。然后紧跟一个浮点型数据作为填补位数满足其存储对其要求。
strcut PointXYZ{
float x;
float y;
float z;
float padding;
}
然而,当用户在嵌入式平台上寻找编译PCL的时候,增加额外的填补就是浪费存储空间。因此,你可以使用一个简单的不带最后浮点数的PointXYZ结构来替代。此外,如果你的应用程序需要一个包含XYZ的三维数据,RGB信息和每个点的估计法线的PointXYZRGBNormal类型,定义包含以上所有内容的结构是简单的。不需要做其他的更改,从而增加了代码的重用性和可读性。
PCL中有哪些可用的PointT类型
为了涵盖能够想到的所有可能情况,PCL中定义了大量的point类型。下面是一小段。在point_types.hpp中有完整的目录,这个列表很重要,因为在你自己的类型之前,需要了解已有的类型。如果你需要的数据已经存在于PCL,那么就不需要重复定义了。
PointXYZ-成员变量: float x,y,z;
PointXYZ是使用最常见的一个点数据类型,因为他只包含三维坐标XYZ坐标信息,这三个浮点数加一个浮点数来满足存储对其。用户可以利用points[i].data[0],或者points[i].x来访问点的x坐标值。
union{
float data[4];
struct
{
float x;
float y;
float z;
};
};
PointXYZI-成员变量:float x,y,z,intensity;
PointXYZI是一个简单的XYZ坐标加上intensity的point类型。理想情况下,这四个变量将新建一个单独的结构体。并且满足存储对齐,然而,由于point的大部分操作会吧data[4]元素设置成0或者1(用于变换),不能让intensity和xyz在同一个结构体中。如果这样的话其内容会被覆盖。例如:两个点的点积会吧他们的第四个元素设置成0,否则该点积没有意义。诸如此类。因此,对于存储内容对其。用三个额外的浮点数来填补in-tensity,这样在存储方面效率较低。但是符合存储对齐要求。运行效率较高。
union
{
float data[4];
struct
{
float x;
float y;
float z;
};
};
union
{
struct
{
float intensity;
};
float data_c[4];
}
实际案例
点云生成
实现效果
步骤讲解
- 首先新建一个空白的Cpp项目,然后配置项目属性。【属性配置方式看这篇文章:juejin.cn/post/713238…
- 导入pcl依赖库,由于我们的类型点都是在pcl_types下面的,所以我们需要导入pcl_types这个头文件。又由于我们需要将点云文件保存成pcd文件,所以我们需要导入pcl_io头文件。
- 这里我们设置点的宽度,也就是width属性,它能够确定无序点云中点的个数,能够确定有序点云中点的宽度
- 然后我们设置点云的height属性,如果height为1,那么就是无序点云。否则他就是代表有序点云的高度
- 规定我们的点云中有多少个点,通过resize方法。
- 最后通过savePCDFileASCII来保存点云模型。
- 运行程序,最后用cloudcompare预览生成的点云模型
代码实现
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
int main() {
pcl::PointCloud<pcl::PointXYZ> cloud;
cloud.width = 5;
cloud.height = 1;
cloud.is_dense = true;
cloud.points.resize(cloud.width*cloud.height);
for (auto &point : cloud) {
point.x = 1024 * rand() / (RAND_MAX + 1.0f);
point.y = 1024 * rand() / (RAND_MAX + 1.0f);
point.z = 1024 * rand() / (RAND_MAX + 1.0f);
}
pcl::io::savePCDFileASCII("test_pcd.pcd", cloud);
for (const auto &point : cloud)
std::cerr << point.x << point.y << point.z << std::endl;
system("pause");
return (0);
}
扩展思考 要是我们想给点云上色,那该怎么办? 其实很简单,我们只要使用PointXYZGRB这个点材质就可以了。
int main() {
pcl::PointCloud<pcl::PointXYZRGB> cloud;
cloud.width = 10000;
cloud.height = 1;
cloud.is_dense = true;
cloud.points.resize(cloud.width*cloud.height);
for (auto &point : cloud) {
point.x = 1024 * rand() / (RAND_MAX + 1.0f);
point.y = 1024 * rand() / (RAND_MAX + 1.0f);
point.z = 1024 * rand() / (RAND_MAX + 1.0f);
point.rgb = 0xff00ff;
}
pcl::io::savePCDFileASCII("test_pcd.pcd", cloud);
for (const auto &point : cloud)
std::cerr << point.x << point.y << point.z << std::endl;
system("pause");
return (0);
}
效果
【PCL点云之旅03-PCL点的类型】 到此结束,如果您觉得对您有帮助的话,可以点赞收藏一下哦。您的支持就是对我最大的鼓励,能让我得到更多的推送流量,帮助到更多的人,最后感谢您花费宝贵的时间认真的阅读这篇文章。如果说您有什么需要我改进的建议欢迎到评论区一起和我讨论❤❤❤