PCL自定义点类型

除了pcl已定义点类型,参考http://www.cnblogs.com/li-yao7758258/p/6433445.html

很多时候都需要自定义所需点类型,定义方法如下

以下例子是创建新的点类型,数据中包含X,Y,Z,PC1,PC2,meanPC(平均曲率),作为参考


step 1 新建myPointType.h

#define PCL_NO_PRECOMPILE

#ifndef MYPOINTTYPE_H
#define MYPOINTTYPE_H

#include <pcl/point_types.h>

struct XYZ_CURVA
{
	PCL_ADD_POINT4D;
	union
	{
		float coordinate[3];
		struct
		{
			float x;
			float y;
			float z;
		};
	};
	float pc1;
	float pc2;
	float mean_pc;
	EIGEN_MAKE_ALIGNED_OPERATOR_NEW;
}EIGEN_ALIGN16;


POINT_CLOUD_REGISTER_POINT_STRUCT(XYZ_CURVA,// 注册点类型宏
	(float, x, x)
	(float, y, y)
	(float, z, z)
	(float, pc1, pc1)
	(float, pc2, pc2)
	(float, mean_pc, mean_pc)
	)

#endif


step 2 cpp中使用
法线和曲率计算参见官网法线例子曲率计算例子如下(并不是真正数学意义上的曲率

pcl::PointCloud<pcl::Normal>::Ptr cloud_with_normals;
	pcl::PointCloud<pcl::PrincipalCurvatures>::Ptr principal_curvatures;
	pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> normal_estimation;
	normal_estimation.setInputCloud(cloud);
	pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
	normal_estimation.setSearchMethod(tree);
	//适合本实验数据的k值
	normal_estimation.setKSearch(60);
	normal_estimation.compute(*cloud_with_normals);
	// Setup the principal curvatures computation
	pcl::PrincipalCurvaturesEstimation<pcl::PointXYZ, pcl::Normal, pcl::PrincipalCurvatures> principal_curvatures_estimation;

	// Provide the original point cloud (without normals)
	principal_curvatures_estimation.setInputCloud(cloud);
	// Provide the point cloud with normals
	principal_curvatures_estimation.setInputNormals(cloud_with_normals);
	// Use the same KdTree from the normal estimation
	principal_curvatures_estimation.setSearchMethod(tree);
	principal_curvatures_estimation.setKSearch(60);
	// Actually compute the principal curvatures
	principal_curvatures_estimation.compute(*principal_curvatures);
	pcl::io::savePCDFile("temp/curva_out.pcd", *principal_curvatures);
	pcl::io::savePCDFile("temp/normal_out.pcd", *cloud_with_normals);

将每个点坐标以及计算好的数据保存至新文件

int size = cloud->size();
	pcl::PointCloud<XYZ_CURVA> xyz_curva;
	xyz_curva.points.resize(size);
	xyz_curva.width = size;
	xyz_curva.height = 1;
	for (int i = 0; i < size; i++)
	{
		xyz_curva.points[i].x = cloud->points[i].x;
		xyz_curva.points[i].y = cloud->points[i].y;
		xyz_curva.points[i].z = cloud->points[i].z;

		xyz_curva.points[i].pc1 = principal_curvatures->points[i].pc1;
		xyz_curva.points[i].pc2 = principal_curvatures->points[i].pc2;
		xyz_curva.points[i].mean_pc = (principal_curvatures->points[i].pc1 + principal_curvatures->points[i].pc2)/2;
	}
	pcl::io::savePCDFile("temp/test.pcd", xyz_curva);

存在问题:

IntelliSense:  常量表达式中不允许该运算符 myPointType.h (但是最终结果不受影响,编译器或者版本的问题maybe)


### 创建自定义类型及其构造函数 为了在PCL中创建和使用自定义类型,需要遵循特定的结构化方法。这不仅涉及定义新的数据结构,还需要向PCL注册该新类型以便能够被识别和支持。 #### 定义自定义类型的数据结构 首先,在C++头文件中声明一个新的类型。通常情况下,建议继承于`sensor_msgs::PointCloud2`中的字段布局以保持兼容性: ```cpp struct MyCustomPoint { PCL_ADD_POINT4D; // 添加必要的宏来支持基本坐标系操作 float intensity; uint16_t ring; EIGEN_MAKE_ALIGNED_OPERATOR_NEW // 确保内存对齐 } EIGEN_ALIGN16; // 数据结构按16字节边界对齐 ``` 上述代码片段展示了如何扩展默认表示形式[^4]。这里增加了强度(`intensity`)以及激光雷达扫描线编号(`ring`)作为额外属性。 #### 注册自定义类型 为了让PCL知道这种新型态的存在,并允许其内部机制对其进行处理,必须执行如下步骤完成注册过程: ```cpp POINT_CLOUD_REGISTER_POINT_STRUCT(MyCustomPoint, (float, x, x) (float, y, y) (float, z, z) (float, intensity, intensity) (uint16_t, ring, ring)) ``` 这段宏调用告诉编译器有关此结构的信息,使得可以像其他标准类型一样对待它。 #### 构造函数实现 对于大多数应用来说,默认无参构造就足够用了;然而如果希望提供更复杂的初始化逻辑,则可以通过重载构造函数来进行增强: ```cpp MyCustomPoint() : intensity(0), ring(0) {} // 或者带有参数列表的形式 MyCustomPoint(float _x, float _y, float _z, float _i, uint16_t r) : pcl::_PointXYZI(x=_x,y=_y,z=_z,intensity=_i), ring(r) {} ``` 以上实现了两种不同方式下的构造函数版本——一个是简单的零值初始化,另一个接受具体数值输入用于实例化对象时赋初值。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值