Aniss Louahadj
Aniss Louahadj

Reputation: 21

Point Cloud Library (PCL) : Extract only the vertices of a surface

I need some help using the PCL library. I am just a beginner with point clouds.

I have a large point cloud from which I extract planes. I end up with 6 surfaces stored separately in a different point cloud each. I use XYZRGB points. However, each point cloud ends up coming with thousands of points.The surfaces ploted using matplotlib

pcl::PointCloud<pcl::PointXYZRGB>::Ptr Surfacei

Size of Surface1 before : 216224 
Size of Surface2 before : 5407 
Size of Surface3 before : 4168 
Size of Surface4 before : 7298 
Size of Surface5 before : 5621 
Size of Surface6 before : 30474 

However, I need to reduce this number of points as it is really big for what I need. I ended up using the pcl::ConvexHull class by doing so :

pcl::ConvexHull<pcl::PointXYZRGB> chull;
chull.setInputCloud(Surfacei);
chull.reconstruct(*Surfacei);

The number of points significantly decreased :

Size of Surface1 before : 30 
Size of Surface2 before : 21 
Size of Surface3 before : 127 
Size of Surface4 before : 21 
Size of Surface5 before : 25 
Size of Surface6 before : 17 

The news plot looks like this

As the planes are quadrilaterals I would like to only extract the coordinates of the vertices of each plane but I couldn't find anything to help doing so.

Could someone help me with this please ?

Upvotes: 2

Views: 1558

Answers (3)

Sant
Sant

Reputation: 41

I think using convex hull will help you find smallest polygon covering all the points and the respective polygon edges and vertices.

Upvotes: 1

Mark Loyman
Mark Loyman

Reputation: 2170

If you want to reduce the number of points in a point cloud, you can use a VoxelGrid filter.

Official Tutorial: Downsampling a PointCloud using a VoxelGrid filter

Usage example (from above tutorial):

  pcl::VoxelGrid<pcl::PCLPointCloud2> sor;
  sor.setInputCloud (cloud);
  sor.setLeafSize (0.01f, 0.01f, 0.01f);
  sor.filter (*cloud_filtered);

Upvotes: 0

Jib Ran
Jib Ran

Reputation: 11

In the following piece of code, I to extract the major plane (largest roughly planar surface) from a point cloud (cloud) to a new point cloud (cloud_segmented). I can guarantee that that this works. From this plane, you can easily extract the vertices by finding the extreme coordinates. What you will need to figure out, however, is how to extend this to get multiple planes.

Also, in your particular example, did you visualize your extracted surfaces? If you do get a surface of points, you can easily extract the extreme points to get your vertices.

    pcl::PointCloud<pcl::PointXYZ> cloud;
    pcl::PointCloud<pcl::PointXYZ> cloud_segmented;

    pcl::ModelCoefficients coefficients;
    pcl::PointIndices::Ptr inliers(new pcl::PointIndices());

    pcl::SACSegmentation<pcl::PointXYZ> segmentation;
    segmentation.setModelType(pcl::SACMODEL_PLANE);
    segmentation.setMethodType(pcl::SAC_RANSAC);
    segmentation.setMaxIterations(1000);
    segmentation.setDistanceThreshold(0.01);
    segmentation.setInputCloud(cloud.makeShared());
    segmentation.segment(*inliers, coefficients);

    pcl_msgs::ModelCoefficients ros_coefficients;
    pcl_conversions::fromPCL(coefficients, ros_coefficients);
    ros_coefficients.header.stamp = input.header.stamp;
    coef_pub.publish(ros_coefficients);

    pcl_msgs::PointIndices ros_inliers;
    pcl_conversions::fromPCL(*inliers, ros_inliers);
    ros_inliers.header.stamp = input.header.stamp;
    ind_pub.publish(ros_inliers);

    pcl::ExtractIndices<pcl::PointXYZ> extract;
    extract.setInputCloud(cloud.makeShared());
    extract.setIndices(inliers);
    extract.setNegative(false);
    extract.filter(cloud_segmented);

Upvotes: 0

Related Questions