Как включить пользовательские ограничения / рейтинги в оценку плоскости RANSAC?

Я пытаюсь сегментировать плоскость из облака точек с помощью библиотеки Point Cloud, и у меня есть некоторая предварительная информация о модели плоскости (т.е. нормаль должна быть похожа на ось z, а высота (d) должна быть около 0) .

Есть ли способ заставить алгоритм RANSAC предпочитать коэффициенты, аналогичные моей предыдущей модели? Я думаю, что это можно сделать либо путем включения ограничений в модель, либо путем изменения рейтинга выбранных самолетов.

Я попытался отфильтровать данные с помощью сквозного фильтра, который сохраняет только точки, которые находятся вокруг предыдущей плоскости. Затем я использовал объект SACSegmentation, чтобы найти плоскость на отфильтрованных данных с моделью нормальной плоскости и допуском на нормальный угол.

Я также пробовал использовать модель параллельной плоскости.


  pcl::PointIndices::Ptr indices_for_segmentation(new pcl::PointIndices);
  pcl::PassThrough<pcl::PointXYZL> pass_through;
  pass_through.setInputCloud(cloud_);
  pass_through.setIndices(clean_indices);
  pass_through.setFilterFieldName("z");
  pass_through.setFilterLimits(z_min_lim, z_max_lim);
  pass_through.filter(indices_for_segmentation->indices);


  pcl::PointIndices::Ptr inliers(new pcl::PointIndices);
  pcl::SACSegmentation<pcl::PointXYZL> ransac;
  ransac.setOptimizeCoefficients(true);
  ransac.setIndices(indices_for_segmentation);
  ransac.setModelType(pcl::SACMODEL_PERPENDICULAR_PLANE);
  ransac.setMethodType(pcl::SAC_RANSAC);
  ransac.setDistanceThreshold(plane_thresh);
  ransac.setInputCloud(cloud_);
  ransac.setAxis(Eigen::Vector3f(0, 0, 1));  // search around the z axis
  ransac.setEpsAngle(pcl::deg2rad(5));
  ransac.segment(*inliers, *coefficients_);

Проблемы с текущим решением заключаются в том, что

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

person gilad    schedule 16.07.2019    source источник


Ответы (1)


Мне кажется, что у вас есть некоторые недопонимания относительно того, как использовать PCL.

Вы объявляете оценщик RANSAC с помощью pcl::SACSegmentation<pcl::PointXYZL>.

Если вы предоставляете только XYZ данные, как, по вашему мнению, RANSAC будет вычислять угловую разницу между нормалью точки и нормалью поверхности? Верно, не может.

Итак, прежде всего, вам нужно вычислить нормали для входного облака. Дополнительную информацию см. В этом руководстве.

Когда у вас есть нормали, вам просто нужно внести незначительные изменения в существующий код.

pcl::PointIndices::Ptr inliers(new pcl::PointIndices);

pcl::SACSegmentationFromNormals<pcl::PointXYZL, pcl::Normal> ransac; // ** change to SACSegmentationFromNormals
ransac.setOptimizeCoefficients(true);
ransac.setIndices(indices_for_segmentation);
ransac.setModelType(pcl::SACMODEL_NORMAL_PLANE);
ransac.setMethodType(pcl::SAC_RANSAC);
ransac.setDistanceThreshold(plane_thresh);
ransac.setInputCloud(cloud_);
ransac.setInputNormals(normals_); // ** set input normals
ransac.setAxis(Eigen::Vector3f(0, 0, 1));  // search around the z axis
ransac.setEpsAngle(pcl::deg2rad(5));
ransac.segment(*inliers, *coefficients_);

Надеюсь это поможет. Удачи!

person kanstar    schedule 17.07.2019
comment
Я исправил свой вопрос, я фактически использовал SACMODEL_PERPENDICULAR_PLANE, который сравнивает нормаль вычисленной плоскости и проверяет, находится ли она в пределах epsAngle от данной (предыдущей) оси, используемой в setAxis - person gilad; 17.07.2019