PCL分割——带条件的欧几里得聚簇

Conditional Euclidean Clustering

该算法与欧几里得聚簇聚簇方法流程无区别。最大的特点在于需要用户传入一个函数指针,来指明点和点之间的合并规则。但该类会在循环的过程中调用判断条件,因此聚簇性能会受到影响。

使用示例
bool enforceNormalOrIntensitySimilarity (const PointTypeFull& point_a, const PointTypeFull& point_b, float /*squared_distance*/)
{
  //此处是直接将点的法向量数值映射为一个3维向量,避免了一次拷贝。用于点乘计算夹角。
  Eigen::Map<const Eigen::Vector3f> point_a_normal = point_a.getNormalVector3fMap (), point_b_normal = point_b.getNormalVector3fMap ();
  if (std::abs (point_a.intensity - point_b.intensity) < 5.0f)
    return (true);
  if (std::abs (point_a_normal.dot (point_b_normal)) > std::cos (30.0f / 180.0f * static_cast<float> (M_PI)))
    return (true);
  return (false);
}

int main()
{
  //先填充XYZI数据
  pcl::copyPointCloud(*cloud_out, *cloud_with_normals);
  //计算法向量
  pcl::NormalEstimation<PointTypeIO, PointTypeFull> ne;
  ne.setInputCloud(cloud_out);
  ne.setSearchMethod(search_tree);
  ne.setRadiusSearch(300.0);
  ne.compute(*cloud_with_normals);
  std::cerr << ">> Done: " << tt.toc() << " ms\n";
  pcl::ConditionalEuclideanClustering<PointTypeFull> cec(true);

  cec.setInputCloud(cloud_with_normals);
  //添加条件
  cec.setConditionFunction(&enforceIntensityOrNormalSimilarity);

  cec.setClusterTolerance(500.0);
  cec.setMinClusterSize(cloud_with_normals->size() / 1000);
  cec.setMaxClusterSize(cloud_with_normals->size() / 5);
  cec.segment(*clusters);
  cec.getRemovedClusters(small_clusters, large_clusters);
  std::cerr << ">> Done: " << tt.toc() << " ms\n";
}

对于条件函数的编写有着固定的格式要求。

  1. 返回值必须为bool
  2. 前两个参数必须为与分类示例模板类型相同的两个点
  3. 第三个参数必须为float用来传入两点之间的平方距离
posted @ 2025-12-15 14:59  Ytytyty  阅读(22)  评论(0)    收藏  举报