【问题标题】:To extract a set of feature and cluster data from the given point cloud data从给定的点云数据中提取一组特征和聚类数据
【发布时间】:2017-03-24 03:52:11
【问题描述】:

目前我正在使用 PCL 1.8.0,我们有一个盘子的样本云数据,其中一些组件安装在盘子上,这些组件在实际盘子上方几厘米处。

这是包含集群和特征数据的云数据。 Cloud Data

通过使用欧几里得聚类提取,我能够从样本数据中获取聚类计数和聚类形状,并且这些聚类会根据聚类数据和形状保存到不同的 PCD 中,如下所示。 Extracted Cluster Data

现在,如果您在上图中观察到,根据我的要求,我们只获得了集群的外边界,我希望将集群的整个外边界和内部特征写入单独的 PCD 文件,以便进一步计算,

谁能建议我如何从给定的云数据中提取集群和特征数据并将其写入单独的 PCD 文件。

任何建议都会有所帮助

提前致谢

【问题讨论】:

    标签: c++ visual-studio windows-7 point-cloud-library


    【解决方案1】:

    解决问题的一种可能方法:

    1. 按照您已经在做的那样计算集群。
    2. 选择您感兴趣的集群。
    3. 计算包含您的集群的minimum oriented bounding box
    4. 使用计算框裁剪原始点云,得到框内的所有点。

    PCL forums 中描述了计算最小方向边界框的过程。但是,为了方便和进一步参考,这里是 Nicola Fioraio 的解决方案大纲:

    1) 计算质心 (c0, c1, c2) 和归一化协方差

    2) 计算特征向量 e0, e1, e2。参考系统将是 (e0, e1, e0 X e1) --- 注意:e0 X e1 = +/- e2

    3) 移动该 RF 中的点 --- 注意:旋转矩阵 (e0, e1, e0 X e1) & (c0, c1, c2) 给出的变换必须反转

    4) 计算对角线的最大值、最小值和中心

    5) 给定一个以原点为中心且大小为 (max_pt.x - min_pt.x, max_pt.y - min_pt.y, max_pt.z - min_pt.z) 的框,您必须应用的变换是 Rotation = (e0 , e1, e0 X e1) & 平移 = 旋转 * center_diag + (c0, c1, c2)

    【讨论】:

    • 嗨 Dexter,首先感谢您的回复,正如您所建议的,我将制作 PCL 可能的最小定向边界框,在制作框后我应该如何从我的主云中提取特征。可能吗?如果可能的话,您能否就如何提取指定特征提出任何建议,任何建议都会有所帮助和感激,谢谢您
    • 您可以获得落在 mOBB 内的点的索引,并使用它们来选择您计算的特征。另外,如果您觉得上一个答案有帮助,请务必接受:)
    • 感谢您的建议,我试图标记您的答案,但由于声誉低,我无法标记您的答案
    【解决方案2】:

    首先感谢您的建议。

    正如您对 PCA 和边界框所建议的那样,我创建了一个边界框,并且我还可以在 PCL 可视化工具中查看创建的框,现在在获得边界框之后,我的目标是将生成的 Cube 保存到单独的 PCD 文件以供进一步计算。

    这是我用于生成边界框的代码,任何人都可以建议我如何将生成的 Cube 保存到单独的 PCD 文件中

    int BoundingBox(pcl::PointCloud<pcl::PointXYZ>::Ptr point_cloud_ptr)
    {
    
       // compute principal direction
       Eigen::Vector4f centroid;
       pcl::compute3DCentroid(*point_cloud_ptr, centroid);
       Eigen::Matrix3f covariance;
       computeCovarianceMatrixNormalized(*point_cloud_ptr, centroid,covariance);
       Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> eigen_solver(covariance,  Eigen::ComputeEigenvectors);
       Eigen::Matrix3f eigDx = eigen_solver.eigenvectors();
       eigDx.col(2) = eigDx.col(0).cross(eigDx.col(1));
    
       // move the points to the that reference frame
       Eigen::Matrix4f p2w(Eigen::Matrix4f::Identity());
       p2w.block<3,3>(0,0) = eigDx.transpose();
       p2w.block<3,1>(0,3) = -1.f * (p2w.block<3,3>(0,0) * centroid.head<3>());
       pcl::PointCloud<pcl::PointXYZ> cPoints;
       pcl::transformPointCloud(*point_cloud_ptr, cPoints, p2w);
    
       pcl::PointXYZ min_pt, max_pt;
       pcl::getMinMax3D(cPoints, min_pt, max_pt);
       const Eigen::Vector3f mean_diag = 0.5f*(max_pt.getVector3fMap() + min_pt.getVector3fMap());
    
       // final transform
       const Eigen::Quaternionf qfinal(eigDx);
       const Eigen::Vector3f tfinal = eigDx*mean_diag + centroid.head<3>();
    
       // draw the cloud and the box
       pcl::visualization::PCLVisualizer viewer;
       viewer.addPointCloud(point_cloud_ptr);
       viewer.addCube(tfinal, qfinal, max_pt.x - min_pt.x, max_pt.y - min_pt.y, max_pt.z - min_pt.z);
       viewer.spin();
    
       return(0);
      }
    

    任何建议都会有所帮助。 提前致谢

    【讨论】:

      猜你喜欢
      • 2020-07-18
      • 2019-12-09
      • 2016-10-23
      • 1970-01-01
      • 2019-04-09
      • 2012-09-24
      • 2021-08-09
      • 1970-01-01
      • 2012-02-09
      相关资源
      最近更新 更多