c++point-cloud-librarypoint-cloudsnormals

How can I compute a normal for each point in cloud


My issue is this: I have cloud of 3D points. I want to attribute each normal to each point. From PCL tutorial :

// 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);

I can found only all cloud normals, I would like assigned for each point given its exact normal.


Solution

  • I am assuming you have point cloud of type say pcl::PointCloud<pcl::PointXYZRGB> and you want to assign your estimated surface normals to each point of your point cloud.

    Surface normals are estimated for every point of your input point cloud. So size of surface normal point cloud is equal to size of input point cloud.

    You can create another point cloud of type pcl::PointCloud<pcl::PointXYZRGBNormal> which can hold the information for corresponding normals along with location and color of point. Then write a for loop for assignment.

    Below is code snippet for that:

    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;
    }
    

    I hope this helps.