使用PCL的OrganizedMultiPlaneSegmentation出现未定义引用编译错误
使用PCL OrganizedMultiPlaneSegmentation时的链接错误解决
问题现象
链接器抛出未定义引用错误:
/usr/bin/ld: CMakeFiles/multiplane.dir/multiplane.cpp.o: in function `main': multiplane.cpp:(.text+0x41d): undefined reference to `pcl::OrganizedMultiPlaneSegmentation<pcl::PointXYZ, pcl::PointNormal, pcl::PointXYZL>::segment(std::vector<pcl::ModelCoefficients, std::allocator<pcl::ModelCoefficients> >&, std::vector<pcl::PointIndices, std::allocator<pcl::PointIndices> >&)' collect2: error: ld returned 1 exit status make[2]: *** [CMakeFiles/multiplane.dir/build.make:192: multiplane] Error 1 make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/multiplane.dir/all] Error 2 make: *** [Makefile:84: all] Error 2
仅移除segment函数调用后编译正常,说明问题出在OrganizedMultiPlaneSegmentation的使用逻辑上。
代码中的核心错误
- 未声明
multiplanesegment对象:直接调用multiplanesegment.setInputCloud,但从未定义该变量,导致链接器无法找到对应函数实现。 - 模板参数与点类型不匹配:
OrganizedMultiPlaneSegmentation需要法线信息,但你仅使用了不含法线的pcl::PointXYZ类型,且未匹配正确的模板参数组合。 - 语法与逻辑疏漏:点云声明末尾缺少分号,且未加载输入PCD文件,空点云会导致后续操作异常。
修正后的完整代码
#include <iostream> #include <pcl/ModelCoefficients.h> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/visualization/cloud_viewer.h> #include <pcl/sample_consensus/method_types.h> #include <pcl/sample_consensus/model_types.h> #include <pcl/segmentation/sac_segmentation.h> #include <pcl/filters/passthrough.h> #include <pcl/filters/extract_indices.h> #include <pcl/common/common.h> #include <thread> #include <chrono> #include <Eigen/Dense> #include <pcl/segmentation/organized_multi_plane_segmentation.h> #include <pcl/features/normal_3d.h> // 法线计算依赖头文件 int main(int argc, char** argv){ // 检查输入参数合法性 if (argc != 2) { std::cerr << "Usage: ./multiplane <pcd_file_path>" << std::endl; return -1; } // 加载点云文件 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>); if (pcl::io::loadPCDFile(argv[1], *cloud) == -1) { std::cerr << "Failed to read file: " << argv[1] << std::endl; return -1; } // 计算点云法线(OrganizedMultiPlaneSegmentation必须输入法线) pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals (new pcl::PointCloud<pcl::PointNormal>); pcl::NormalEstimation<pcl::PointXYZ, pcl::PointNormal> ne; ne.setInputCloud(cloud); pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ>); ne.setSearchMethod(tree); ne.setRadiusSearch(0.03); // 根据点云密度调整搜索半径 ne.compute(*cloud_with_normals); // 声明OrganizedMultiPlaneSegmentation对象,匹配模板参数 pcl::OrganizedMultiPlaneSegmentation<pcl::PointXYZ, pcl::PointNormal, pcl::PointXYZL> multiplanesegment; // 设置分割参数 multiplanesegment.setInputCloud(cloud); multiplanesegment.setInputNormals(cloud_with_normals); multiplanesegment.setMinInliers(100); // 最小内点数量,按需调整 multiplanesegment.setAngularThreshold(0.0174533); // 1度对应的弧度值,平面间角度阈值 multiplanesegment.setDistanceThreshold(0.01); // 点到平面的距离阈值,按需调整 // 执行平面分割 std::vector<pcl::ModelCoefficients> model_coefficients; std::vector<pcl::PointIndices> inlier_indices; std::vector<pcl::PointXYZL> labels; multiplanesegment.segment(model_coefficients, inlier_indices, labels); std::cout << "Successfully segmented " << model_coefficients.size() << " planes." << std::endl; return 0; }
CMakeLists优化(匹配环境版本)
你的原有配置基本可用,建议指定PCL版本为1.10(匹配你的Ubuntu 20.04环境),同时明确依赖组件:
cmake_minimum_required(VERSION 3.5 FATAL_ERROR) project(multiplane_test) find_package(PCL 1.10 REQUIRED COMPONENTS segmentation features io) include_directories(${PCL_INCLUDE_DIRS}) link_directories(${PCL_LIBRARY_DIRS}) add_definitions(${PCL_DEFINITIONS}) add_executable(multiplane multiplane.cpp) target_link_libraries(multiplane ${PCL_LIBRARIES})
关键注意事项
OrganizedMultiPlaneSegmentation仅针对有序点云设计(如深度相机输出的行列结构化点云),无序点云需改用其他分割方法。- 该类必须输入法线信息,因此必须先通过
NormalEstimation模块计算点云法线。 - 模板参数顺序严格为:输入点类型、法线点类型、输出标签点类型,需与代码中使用的类型完全匹配。
内容的提问来源于stack exchange,提问作者C S
相关产品推荐
相关产品推荐

