# Three methods to iterate every point in pointcloud of PCL（三种遍历点云的方式）

2019/08/10 10:13

### The most common way to do this is by subscript in the [] operand<sup>[1]</sup>

pcl::PointCloud<pcl::PointXYZ>::Ptr pointCloud;
for（int nIndex = 0； nIndex < pointCloud->points.size (); nIndex++）
{
pointCloud->points[nIndex].x;
pointCloud->points[nIndex].y;
pointCloud->points[nIndex].z;
}


### The more efficient way is to use an iterator <sup>[2]</sup><sup>[3]</sup>

#### The example in Euclidean Cluster Extraction of pcl tutorials is well known <sup>[2]</sup>.

Extract the indices cluster_indices then use it to iterate each pointcloud from cluster_indices.begin () to cluster_indices.end (). Next step is to iterate every point in the pointcloud from it->indices.begin (); to it->indices.end (). The code snippet is:

    std::vector<pcl::PointIndices> cluster_indices;
pcl::EuclideanClusterExtraction<pcl::PointXYZ> ec;
ec.setClusterTolerance (0.02); // 2cm
ec.setMinClusterSize (100);
ec.setMaxClusterSize (25000);
ec.setSearchMethod (tree);
ec.setInputCloud (cloud_filtered);
ec.extract (cluster_indices);

int j = 0;
for (std::vector<pcl::PointIndices>::const_iterator it = cluster_indices.begin (); it != cluster_indices.end (); ++it)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_cluster (new pcl::PointCloud<pcl::PointXYZ>);
for (std::vector<int>::const_iterator pit = it->indices.begin (); pit != it->indices.end (); ++pit)
cloud_cluster->points.push_back (cloud_filtered->points[*pit]); //*
cloud_cluster->width = cloud_cluster->points.size ();
cloud_cluster->height = 1;
cloud_cluster->is_dense = true;

std::cout << "PointCloud representing the Cluster: " << cloud_cluster->points.size () << " data points." << std::endl;
std::stringstream ss;
ss << "cloud_cluster_" << j << ".pcd";
writer.write<pcl::PointXYZ> (ss.str (), *cloud_cluster, false); //*
j++;
}


#### Last way do iteration but only Eigen::Vector3f values of points can be extract instead of a PCL point. <sup>[3]</sup>

If having trouble to save memory consumption, try this! Note: Only if the second way didn't work out!

The advantage of using this iterator is that no indices should be extracted before.

for (std::vector<pcl::PointXYZ, Eigen::aligned_allocator<pcl::PointXYZ> >::iterator it = pointCloud.bigin(); it != cropedCloud.end(); it++)
{
// Return an Eigen::Vector3f of points coordinate.
it->getVector3fMap();  // if double wanted, just say it->getVector3fMap().cast<double>
}


Note:

1. The snippet should be modified to YOUR version before using it
2. pcl::PointXYZ can be replaced by any type of PointT
3. pcl::PointCloud<pcl::PointXYZ>::Ptr pointCloud can be replaced by pcl::PointCloud<pcl::PointXYZ> pointCloud, so by the mean time replace pointCloud->points.size() instead of pointCloud.points.size() */

## What matters to me but it might not be helpful to you

### Let's talk about how to find a way to use data of unknown type

1. pcl::CropBox< PointT > does gives an access to achieve indices.
2. There is an iterator begin () on the PCL namespace website. I guess can use it to iterate all around in the pointcloud.
3. Look for definition at line 442 of point_cloud.h, which returns points.begin () Click the function begin () in the const_iterator begin () const.
4. In the tutorial of iterating pointcloud<sup>[2]</sup>, pointcloud->begin() is neither indices nor points. The data structure type it use is std::vector<pcl::PointXYZ, Eigen::aligned_allocator<pcl::PointXYZ> >::iterator, which I got from the error building. Note: Sometimes you don't know what the type it is, but you can got it from the error. What a amazing thing.
5. The most important thing is: how to get the data? So I go through the pcl directory, and search for function points.begin().
6. \$ cd ~/Downloads/nozuonodie/pcl-pcl-1.7.2, grep -rn -ie "points.begin ()". Look for those lines of matched completely function "points.begin ()" in hpp or cpp files.
7. After several attemps, I got it by common/include/pcl/range_image/impl/range_image.hpp:1225: for (typename PointCloudType::const_iterator it = far_ranges.points.begin (); it != far_ranges.points.end (); ++it). Go to line 1225, see Vector3fMapConst current_point = it->getVector3fMap ();, then look for variable current_point
8. In line 1231, this->getImagePoint (current_point, x_real, y_real, range_of_current_point); just go to the definition of getImagePoint.
9. In line 352, function void RangeImage::getImagePoint (const Eigen::Vector3f& point, float& image_x, float& image_y, float& range) const totally matches.
10. In conclusion, member function getVector3fMap() can get Eigen::Vector3f from the point by iterator. And also can be proved by referece <sup>[3]</sup>.

### References:

<span id="jump1">[1]</span> Filtering a PointCloud using a PassThrough filter <span id="jump2">[2]</span> Euclidean Cluster Extraction <span id="jump3">[3]</span> Creating a PCL point cloud using a container of Eigen Vector3d

0
0 收藏

0 评论
0 收藏
0