我想使用PCL库从点云提取水平面。有一个已知的程序使用RANSAC提取平面,该程序将找到最大的平面,但是我想将搜索限制为仅水平面(Ax+By+C*z+D=0,其中A、B=0且C=1)。下面的代码试图通过沿着z轴添加Axis向量来实现(0,0,1)和EpsAngle容差。
然而,它似乎并不像我期望的那样工作,看起来使用setAxis()设置Axis vector根本不会影响内层平面,我继续从相邻的墙壁而不是地板(水平)平面或沿着指定轴定向的平面获取侧平面。
点云是这样的,有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
2条答案
按热度按时间dtcbnfnu1#
使用
SACMODEL_PARALLEL_PLANE
代替SACMODEL_PLANE
和setAxis
。使用Z
-轴作为轴,因此setAxis(Eigen::Vector3f::UnitZ())
。您还应该考虑使用
setEpsAngle()
,不要将自己限制在完美的平面上。fafcakar2#
我设法使用SACMODEL_PARALLEL_PLANE和setAxis(1,0,0)检测到一个水平表面。这很奇怪,但它可以工作(我希望提供0,0,1)。
可能是pcl中的一个bug(我用的是1.13)。