• Three methods to iterate every point in pointcloud of PCL(三种遍历点云的方式)


    The most common way to do this is by subscript in the [] operand[1]

    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 [2] [3]

    The example in Euclidean Cluster Extraction of pcl tutorials is well known [2].

    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. [3]

    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[2], 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 [3].

    References:

    [1] Filtering a PointCloud using a PassThrough filter
    [2] Euclidean Cluster Extraction
    [3] Creating a PCL point cloud using a container of Eigen Vector3d

  • 相关阅读:
    Linux中批量添加文件和修改文件小笔记
    scp 命令快速使用讲解
    使用Apache Spark 对 mysql 调优 查询速度提升10倍以上
    阿里云CentOS-7.2安装mysql
    yum安装网络配置图形界面
    忘记了root密码,如何进入系统?
    Linux学习之竿头直上
    Linux命令之初出茅庐
    Linux学习之要点必备
    阿里云CentOS7.2服务器的安装
  • 原文地址:https://www.cnblogs.com/linweilin/p/11330677.html
Copyright © 2020-2023  润新知