问题描述
我想使用 PCL 库从点云中提取水平面。有一个使用 RANSAC 提取平面的已知程序,可以找到最大的平面,但是我想将搜索限制为仅水平平面 (Ax+By+C*z+D=0,其中 A、B=0 和 C=1)。 以下代码尝试通过向 SACSegmentation 对象添加 Axis 向量、沿 z 轴 (0,1) 和 EpsAngle 容差来实现该功能。
然而,它似乎不像我期望的那样工作,而且看起来用 setAxis() 设置轴向量根本不影响内层平面,我一直从相邻的墙壁而不是地板(水平)获取侧平面平面,或沿指定轴定向的平面。
点云有 4 个墙(因此有 4 个平面)和一个地板,这也应该产生第五个平面。
pcl::PointCloud<pcl::PointXYZ>::Ptr pointcloudIn(new pcl::PointCloud<pcl::PointXYZ>());
// Segment the ground
pcl::ModelCoefficients::Ptr plane (new pcl::ModelCoefficients);
pcl::PointIndices::Ptr inliers (new pcl::PointIndices);
plane->values.resize(4); // Make room for a plane equation (ax+by+cz+d=0)
pcl::SACSegmentation<pcl::PointXYZ> seg; // Create the segmentation object
seg.setAxis(Eigen::Vector3f(0.,0.,1.)); // Set the axis along which we need to search for a model perpendicular to
seg.setEpsAngle((10.*M_PI)/180.); // Set maximum allowed difference between the model normal and the given axis in radians
seg.setoptimizeCoefficients(true); // Coefficient refinement is required
seg.setMethodType(pcl::SAC_RANSAC);
seg.setModelType(pcl::SACMODEL_PLANE);
seg.setdistanceThreshold(0.05f);
seg.setInputCloud(pointcloudIn);
seg.segment(*inliers,*plane);
// Extract inliers
pcl::ExtractIndices<pcl::PointXYZ> extract;
extract.setInputCloud(pointcloudIn);
extract.setIndices(inliers);
extract.setNegative(false); // Extract the inliers
extract.filter(*pointcloudplane); // pointcloudplane contains the plane
解决方法
使用 SACMODEL_PARALLEL_PLANE
而不是 SACMODEL_PLANE
与 setAxis
一起使用。
使用 Z
-Axis 作为轴,所以 setAxis(Eigen::Vector3f::UnitZ())
。
您还应该考虑使用 setEpsAngle()
来不局限于完美的平面。