user1349663
user1349663

Reputation: 605

Copy PCL Point Cloud while preserving organization or Ransac + Surface Normal Calculation

I have a point cloud

pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGBA>);

that I want to copy into

pcl::PointCloud<pcl::PointXYZRGBA>::Ptr finalcloud (new pcl::PointCloud<pcl::PointXYZRGBA>);

while filtering based on some inliers calculated using ransac.

std::vector<int> inliers;

I am currently doing this as

pcl::copyPointCloud<pcl::PointXYZRGBA>(*cloud, inliers, *finalcloud);

Problem:

Since I want to find the normals for this cloud, I need the organization to be maintained. The copyPointCloud function makes the new point cloud height = 1 (see line 188 of PCL io.hpp ).

Has anyone been able to find normals after performing ransac on a pcl?

Upvotes: 1

Views: 4726

Answers (1)

Ardiya
Ardiya

Reputation: 727

I think this answer is too late and API might changes from 2015.. but I'll answer it.

The normal estimation will work with both organized cloud and unorganized cloud.

Unorganized Cloud

I'm copying the code from http://pointclouds.org/documentation/tutorials/normal_estimation.php In this code, the KdTree will be used to estimate the neighbours.

#include <pcl/point_types.h>
#include <pcl/features/normal_3d.h>

{
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);

  ... read, pass in or create a point cloud ...

  // Create the normal estimation class, and pass the input dataset to it
  pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
  ne.setInputCloud (cloud);

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

  // cloud_normals->points.size () should have the same size as the input cloud->points.size ()*
}

Organized Cloud

I am copying the code from http://www.pointclouds.org/documentation/tutorials/normal_estimation_using_integral_images.php#normal-estimation-using-integral-images

// load point cloud
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile ("table_scene_mug_stereo_textured.pcd", *cloud);

// estimate normals
pcl::PointCloud<pcl::Normal>::Ptr normals (new pcl::PointCloud<pcl::Normal>);

pcl::IntegralImageNormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
ne.setNormalEstimationMethod (ne.AVERAGE_3D_GRADIENT);
ne.setMaxDepthChangeFactor(0.02f);
ne.setNormalSmoothingSize(10.0f);
ne.setInputCloud(cloud);
ne.compute(*normals);

Upvotes: 1

Related Questions