代码之家  ›  专栏  ›  技术社区  ›  lotfishtaine

如何计算云中每个点的法线

  •  0
  • lotfishtaine  · 技术社区  · 9 年前

    我的问题是:我有三维点云。我想将每个法线都归因于每个点。从PCL教程:

    // Create the normal estimation class, and pass the input dataset to it
    pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
    ne.setInputCloud (cloud.makeShared());
    
    // Create an empty kdtree representation, and pass it to the normal estimation object.
    // Its content will be filled inside the object, based on the given input dataset (as no other search surface is given).
    pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ> ());
    ne.setSearchMethod (tree);
    
    // Output datasets
    pcl::PointCloud<pcl::Normal>::Ptr cloud_normals (new pcl::PointCloud<pcl::Normal>);
    
    // Use all neighbors in a sphere of radius 3cm
    ne.setRadiusSearch (0.03);
    
    // Compute the features
    ne.compute (*cloud_normals);
    

    我只能找到所有云法线,我希望为每个点指定精确的法线。

    2 回复  |  直到 9 年前
        1
  •  4
  •   Satya    8 年前

    我假设你有点云 pcl::PointCloud<pcl::PointXYZRGB> 并且要将估计的曲面法线指定给点云的每个点。

    将为输入点云的每个点估计曲面法线。所以曲面法线点云的大小等于输入点云的尺寸。

    您可以创建另一个类型的点云 pcl::PointCloud<pcl::PointXYZRGBNormal> 其可以保存对应法线的信息以及点的位置和颜色。然后写一个 for 循环进行分配。

    下面是它的代码片段:

    pcl::PointCloud<pcl::PointXYZRGB>& src; // Already generated
    pcl::PointCloud<pcl::PointXYZRGBNormal> dst; // To be created
    
    // Initialization part
    dst.width = src.width;
    dst.height = src.height;
    dst.is_dense = true;
    dst.points.resize(dst.width * dst.height);
    
    // Assignment part
    for (int i = 0; i < cloud_normals->points.size(); i++)
    {
        dst.points[i].x = src.points[i].x;
        dst.points[i].y = src.points[i].y;
        dst.points[i].z = src.points[i].z;
    
        dst.points[i].r = src.points[i].r;
        dst.points[i].g = src.points[i].g;
        dst.points[i].b = src.points[i].b;
    
       // cloud_normals -> Which you have already have; generated using pcl example code 
    
        dst.points[i].curvature = cloud_normals->points[i].curvature;
    
        dst.points[i].normal_x = cloud_normals->points[i].normal_x;
        dst.points[i].normal_y = cloud_normals->points[i].normal_y;
        dst.points[i].normal_z = cloud_normals->points[i].normal_z;
    }
    

    我希望这有帮助。

        2
  •  0
  •   Ademola Oridate    3 年前

    而不是使用 for 循环,您可以使用 pcl::concatenateFields :

        pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
        pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals (new pcl::PointCloud<pcl::PointNormal>); 
        pcl::PointCloud<pcl::Normal>::Ptr normals (new pcl::PointCloud<pcl::Normal>);
        // Use all neighbors in a sphere of radius 3cm
        ne.setRadiusSearch (0.03);
        // Compute the features
        ne.compute (*normals);
        pcl::concatenateFields(*cloud, *normals, *cloud_with_normals);