PCL Cloud Basics

The format to store a 3D image is a Point Cloud, which contains a set of data points captured by the depth sensor in the XYZ coordinate system. In PCL, a Point Cloud is expressed as pcl::PointCloud<PointT>;, which stores the points inside a std::vector. A point cloud contains many different useful information, such as size and coordinates, that can be useful when doing computation. The following tutorial will explore some of the most common features and functions in Point Clouds.

Point Types

As the most commonly used format to store points, a Point Cloud must be able to represent different types of informations. PCL has multiple PointT types that enable this to happen. Each PointT type has a different set of information that it stores, and the user can tell what type of information is passed from the name of the PointT. Some of the most common PointT types are:

• PointXYZ: This is the most common PointT type. It contains the X, Y, and Z coordinates of the point. The user can use point.x, point.y, and point.z to access the X, Y, and Z coordinates, respectively.
• PointXYZI: This includes the basic XYZ coordinates as well as the point’s intensity. The intensity value can be accessed through point.intensity.
• PointXYZRGBA: This includes the basic XYZ coordinates and the color in RGBA values. The RGB values can be accessed through point.r, point.g, and point.b. Compared to PointXYZRGB, this is the better RGB point type to use.
• Normal: This represents the surface normal at a given point. It contains the XYZ coordinates of the normal vector as well as a measure of curvature. Similar to the above point types, the normal XYZ values can be accessed through point.normal_x, point.normal_y, and point.normal_z.
• PointNormal: This includes both the normal and the XYZ coordinates of the point.
• PointXYZRGBNormal: This includes the normal, the XYZ coordinates of the point, and the RGB values of the point.
• PointXYZINormal: This includes, the normal, the XYZ coordinates of the point, and the intensity of the point.

An explanation of other less commonly used point types can be found on PCL’s website: http://pointclouds.org/documentation/tutorials/adding_custom_ptype.php/

Make Copies

One of the most commonly used function in PCL is copyPointCloud(), which lets the user make a copy of one Point Cloud and put it into another Point Cloud. The function takes in two parameters, a pcl::PointCloud cloud_in and a pcl::PointCloud cloud_out, and all the points in cloud_in are copied into cloud_out.

copyPointCloud() is useful in that if there is an existing Point Cloud inside cloud_out, the copying will not overwrite the existing points. Thus, the user can copy multiple cloud_ins into the same cloud_out. Another useful fact about copyPointCloud() is that the cloud_in and cloud_out can consist of different PointT types. For example, a pcl::PointCloud can be copied into pcl::PointCloud, and vice versa.

In my normal estimation in CustomCloud.cpp, I use copyPointCloud() to copy pcl::PointCloud into pcl::PointCloud:

void computeNormals()
{
normals_ = PointCloudWithNormals::Ptr (new PointCloudWithNormals);
pcl::search::KdTree::Ptr tree (new pcl::search::KdTree);

pcl::NormalEstimationOMP<pointt, pointnormalt=""> norm_est;
norm_est.setInputCloud(f_cloud_);
norm_est.setSearchMethod(tree);
norm_est.setKSearch(normal_k_);
norm_est.compute(*normals_);

copyPointCloud(*f_cloud_, *normals_);
}

//Note: f_cloud_ and normals_ were Point Clouds defined outside of the function.
//f_cloud is pcl::PointCloud.
//normals_ is pcl::PointCloud.

When I compute normals from f_cloud_, I created a Point Cloud in normals_ that contains estimated normals. When I use copyPointCloud(), the XYZ and RGB values of f_cloud_ are copied into normals_, thus allowing normals to have both the XYZ and RGB values of the point as well as the normals and curvature values associated with that point.

On the other hand, if a pcl::PointCloud<pcl::PointXYZRGBNormal> cloud_in is copied into a pcl::PointCloud cloud_out, the XYZ and RGB values will be copied, but the cloud_out will not retain the normal information, as it does not have the ability to store it. This also makes copyPointCloud() an easy way to convert point clouds of different point types, such as from PointXYZRGBA to PointXYZ.