PCL自定义点云结构

PCL自定义点云结构

1 背景

以前在使用PCL进行点云处理中,基本都使用PCL自带结构。最近工作中,拿到车端语义点云数据,其中一个任务就是需要点云融合对齐(内部涉及到矢量提取)。由于输出点云需要带对应属性,在PCL采样后也能正常绑定点云结构信息,这时就涉及到自定义点云结构。由于PCL自定义结构有自己的特殊方式,在使用中踩过一些坑,有坑就得填,因此单开篇填坑。

2 方式

2.1 原方式

这里可以按类似如下方式编写代码,然后使用自定义类CustomPoint_t

#define PCL_NO_PRECOMPILE

#include <pcl/point_types.h>
#include <pcl/point_cloud.h>

//1. 自定义结构
struct EIGEN_ALIGN16 CustomPoint_t
{
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW //1.1 申明内存对齐
    PCL_ADD_POINT4D;                //1.2 PCL宏里定义了x,y,z以及一些函数接口
    int other;                      //1.3 定义的其它属性
};

//2. 注册自定义结构
POINT_CLOUD_REGISTER_POINT_STRUCT(CustomPoint_t,
                                (float, x, x)
                                (float, y, y)
                                (float, z, z)
                                (int, other, other));
//3. 测试使用
void test()
{
    pcl::PointCloud<custompoint_t> cloud;
    ...
}

上面代码里需要注意几个点:  

(1) PCL_NO_PRECOMPILE: 定义代码放在包含PCL头文件前面。  

(2) PCL_ADD_POINT4D : 结构体里尽量使用这个宏,不要自己单独定义(x,y,z)坐标,否则还需要单独实现一些函数接口。  

(3) POINT_CLOUD_REGISTER_POINT_STRUCT : 这个宏一定放在没有namespace的外面,如果放在namespace内,会编译报错,如下代码就会报错(注意,注释1里的自定义结构不受这个限制)

...
namespace point
{
    //1. 自定义结构
    struct EIGEN_ALIGN16 CustomPoint_t
    {
        EIGEN_MAKE_ALIGNED_OPERATOR_NEW
        PCL_ADD_POINT4D; 
        int other;
    };

    //2. 注册自定义结构
    POINT_CLOUD_REGISTER_POINT_STRUCT(CustomPoint_t,
                                    (float, x, x)
                                    (float, y, y)
                                    (float, z, z)
                                    (int, other, other));
}
...

2.2 新方式

这里约定编译环境A满足如下条件:  

(1) Eigen版本不低于3.3.7  

(2) c++编译版本不低于17  

(3) 编译器支持(2)的情况下,自动处理内存对齐问题

如果PCL的库由编译环境A编译出,实际工程项目也是在环境A里编译,那么上面EIGEN_ALIGN16EIGEN_MAKE_ALIGNED_OPERATOR_NEW宏可以不再使用,示例中自定义结构部分代码可以改写为如下方式

struct CustomPoint_t
{
    PCL_ADD_POINT4D; //PCL宏里定义了x,y,z以及一些函数接口
    int other;       //定义的其它属性
};

这里需要注意的是,如果PCL库不是在A环境下编译生成,但项目是在A环境下编译,这时使用新的非申明方式编译,可能出现内存对齐错误。即使在代码里进行了宏申明也会可能出错,因为最新的Eigen里已经自动将A环境下的宏定义为了一个空的代码,和不申明宏没有区别。在种情况下,最好的办法就是,PCL源码在当前项目环境进行编译,然后链接。

发表回复

您的电子邮箱地址不会被公开。

蜀ICP备17029856号-1