Сегментируйте только горизонтальную плоскость (0 * x + 0 * y + 1 * z + D = 0) из облака точек с помощью RANSAC и pcl :: SACSegmentation

Я хотел бы извлечь горизонтальную плоскость из облака точек с помощью библиотеки PCL. Существует известная процедура извлечения плоскостей с помощью RANSAC, которая находит самую большую плоскость, однако я хотел бы ограничить поиск только горизонтальными плоскостями (A x + B y + C * z + D = 0, где A, B = 0 и C = 1). Следующий код был попыткой реализовать это путем добавления вектора Axis вдоль оси z (0,0,1) и допуска EpsAngle к объекту SACSegmentation.

Однако, похоже, это не работает так, как я ожидал, и похоже, что установка вектора оси с помощью setAxis () вообще не влияет на плоскость изгиба, я продолжаю получать боковые плоскости от соседних стен, а не плоскость пола (горизонтальную), или плоскость, ориентированная вдоль заданной оси.

Pointcloud таково, что есть 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

person Miroslav Radojević    schedule 07.02.2021    source источник


Ответы (1)


Используйте SACMODEL_PARALLEL_PLANE вместо SACMODEL_PLANE вместе с setAxis. Используйте ось Z в качестве оси, поэтому setAxis(Eigen::Vector3f::UnitZ()).

Вам также следует подумать об использовании setEpsAngle(), чтобы не ограничиваться идеальными самолетами.

person kanstar    schedule 10.02.2021