自定义点云类型使用pcl库函数时出现‘未定义的引用’问题解决
问题描述
自定义的点云类型在使用pcl的滤波函数时出现未定义的引用这一问题,报错如下。MPT::PointOuster是自定义的点云类型。
CMakeFiles/pclfilter.dir/src/main.cpp.o:在函数‘main’中:
main.cpp:(.text+0x1eb):对‘pcl::PCLBase<MPT::PointOuster>::setInputCloud(boost::shared_ptr<pcl::PointCloud<MPT::PointOuster> const> const&)’未定义的引用
问题代码
原来有问题的部分如下:
//----------------AddPointType.h---------------------//
#ifndef ADDPOINTTYPE_H
#define ADDPOINTTYPE_H
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
namespace MPT{//MyPointType
struct PointOuster //Ouster激光雷达给的数据
{
//省略了自定义类型具体内容
EIGEN_MAKE_ALIGNED_OPERATOR_NEW //确保new操作符对齐操作
}EIGEN_ALIGN16; //强制SSE 对齐
}//namespace MPT
POINT_CLOUD_REGISTER_POINT_STRUCT(MPT::PointOuster, //注册点类型宏
//省略
)
#endif
main函数滤波使用部分学习参考了CSDN博主「没事就要敲代码」的原创文章《PCL:点云滤波汇总:算法原理 + 代码实现》,实际使用中对自定义的对象进行滤波。
//-------------------main.cpp---------------------//
#include "AddPointType.h"
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/passthrough.h>
#include <pcl/visualization/cloud_viewer.h>
#include <iostream>
using namespace std;
using namespace MPT;
//这里的头文件是不行的
int main(int argc, char const *argv[])
{
pcl::PointCloud <MPT::PointOuster> ::Ptr cloud(new pcl::PointCloud <MPT::PointOuster>);//待滤波点云
pcl::PointCloud <MPT::PointOuster> ::Ptr cloud_filtered(new pcl::PointCloud <MPT::PointOuster>);//滤波后点云
//读入
cout << "->正在读入点云..." << endl;
pcl::PCDReader reader;
reader.read("../../pclBtoA/new.pcd", *cloud);
cout << "\t\t<读入点云信息>\n" << *cloud << endl;
//直通滤波,即保留某个属性在某个范围内的点
cout << "->正在进行直通滤波..." << endl;
pcl::PassThrough<MPT::PointOuster> pt; //创建滤波器对象
pt.setInputCloud(cloud);
pt.setFilterFieldName("x");
pt.setFilterLimits(-0.1,1);
pt.setFilterLimitsNegative(true);//默认false,保留范围内的点云;true则保留范围外的点云
pt.filter(*cloud_filtered);//执行滤波并保存
//存储滤波后点云
cout << "->正在保存滤波后点云..." << endl;
if(cloud_filtered->empty()){
PCL_ERROR("保存点云为空!\n");
return -1;
}
else{
pcl::io::savePCDFile("../filter1.pcd",*cloud_filtered);
//filter1.pcd为直通滤波结果
cout << "转存成功" << *cloud_filtered << endl;
}
/滤波前后对比可视化//
pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("滤波前后对比"));
/*--视窗1--*/
int v1(0);
viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1); //设置第一个视口在X轴、Y轴的最小值、最大值,取值在0-1之间
viewer->setBackgroundColor(0, 0, 0, v1); //设置背景颜色,0-1,默认黑色(0,0,0)
viewer->addText("before_filtered", 10, 10, "v1_text", v1);
viewer->addPointCloud<MPT::PointOuster>(cloud, "befor_filtered_cloud", v1);
/*--视窗2--*/
int v2(0);
viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);
viewer->setBackgroundColor(0.3, 0.3, 0.3, v2);
viewer->addText("after_filtered", 10, 10, "v2_text", v2);
viewer->addPointCloud<MPT::PointOuster>(cloud_filtered, "after_filtered_cloud", v2);
/*-----设置相关属性-----*/
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "befor_filtered_cloud", v1);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1, 0, 0, "befor_filtered_cloud", v1);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "after_filtered_cloud", v2);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 1, 0, "after_filtered_cloud", v2);
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
return 0;
}
解决方法
**
划重点:#define PCL_NO_PRECOMPILE要放在头文件前面!
**
解决后头文件部分
//----------------AddPointType.h---------------------//
#ifndef ADDPOINTTYPE_H
#define ADDPOINTTYPE_H
#define PCL_NO_PRECOMPILE
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
//----------------main.cpp---------------------//
#include "AddPointType.h"
#define PCL_NO_PRECOMPILE
#include <pcl/filters/passthrough.h>
#include <pcl/filters/impl/passthrough.hpp>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/cloud_viewer.h>
#include <iostream>
其实这个问题有认真看过pcl文档的应该都不会出现,也就我这种刚上路全靠百度和csdn上的零碎知识学pcl的憨憨被困扰了一下下,以此记录,多看文档。