首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PCL在无云副本的八叉树上应用过滤器

PCL在无云副本的八叉树上应用过滤器
EN

Stack Overflow用户
提问于 2018-11-13 00:02:27
回答 2查看 1.3K关注 0票数 0

我有很大的点云,我想在上面应用voxelGrid。但由于点云太大,我有错误,如"[pcl::VoxelGrid::applyFilter] Leaf size is too small for the input dataset. Integer indices would overflow"。所以我想首先从我的点云构建一个八叉树,然后在每个叶子上应用过滤器(即在具有良好索引的点云上应用过滤器)

问题发生在这里,当我应用过滤器时,PCL希望我选择一个PointCloud,它将被保存在其中,并用过滤器的结果替换原始的点云。我想知道是否有可能修改过滤器,使其不删除点,而只将点云中必须删除的索引处的点放入(0,0,0)。

我的代码:

代码语言:javascript
复制
void Octree::applyExample(float x, float y, float z) {
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);

    // Fill in the cloud data
    cloud->width = 100000;
    cloud->height = 1;
    cloud->is_dense = false;
    cloud->points.resize(cloud->width * cloud->height);

    for (size_t i = 0; i < cloud->points.size(); ++i)
    {
        cloud->points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
        cloud->points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
        cloud->points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
    }
    octree.setInputCloud(cloud);
    octree.addPointsFromInputCloud();
    pcl::octree::OctreePointCloud<pcl::PointXYZRGB>::LeafNodeIterator it;
    pcl::octree::OctreePointCloud<pcl::PointXYZRGB>::LeafNodeIterator it_end = octree.leaf_end();
    for (it = octree.leaf_begin(); it != it_end; ++it)
    {

        pcl::IndicesPtr indexVector(new vector<int>);
        pcl::octree::OctreeContainerPointIndices& container = it.getLeafContainer();

        container.getPointIndices(*indexVector);
        FILTREexample(cloud, indexVector, x, y, z);
    }
}

和过滤器:

代码语言:javascript
复制
void FILTREexample(pcl::PointCloud<pcl::PointXYZ>::Ptr pointcloud, pcl::IndicesPtr indices, float x, float y, float z) {
    pcl::VoxelGrid<pcl::PointXYZ> sor;
    sor.setInputCloud(pointcloud);
    sor.setIndices(indices);
    sor.setLeafSize(x, y, z);
    sor.filter(*pointcloud); //The problem occurs here
    //Everytime, the pointcloud is substituted with the result of the filter, but I'd like to still have my "entire" pointcloud, but either with the filtered point deleted, or the filtered point put to 0,0,0.

}

有可能做这样的事情吗?

EN

回答 2

Stack Overflow用户

发布于 2018-11-15 07:20:16

据我所知,没有"pcl“方法可以做到这一点。你应该自己做一些编码来获得你期望的结果。我想到的一个替代方法是:您可以将结果(过滤后的)点云从体素过滤器添加到输入参数pointcloud中,如下所示。这将基本上膨胀您的原始点云,并可能导致速度减慢,因为点云的点存储在std::vector<T>中,并且调整此容器的大小是昂贵的。

代码语言:javascript
复制
...
typedef pcl::PointCloud<pcl::PointXYZ> PC_t;
PC_t::Ptr temp_pc(new PC_t());
// Your voxel grid filter code ...
// ...
sor.filter(temp_pc);
for(auto& p : temp_pc->points)
    pointcloud->push_back(p);

一旦applyExample(...)函数中的循环完成,您将拥有所有初始点和体素过滤点。然后,可以使用pcl::ExtractIndices<T>过滤器删除原始点云(即cloud)中的所有点。请注意,您知道在开始时有多少点,因此您知道要传递给ExtractIndices的索引。您还应该注意,删除循环中的点将使您的八叉树无效,这就是为什么必须推迟删除点的原因。请选中%1以查看pcl::ExtractIndices<T>的使用情况。

这只是一种方法,也可能是效率最低的方法之一,以获得您想要的结果。将另一个点云传递给您的FILTREexample()函数,您将在其上累加temp_pc中的点,这可能有助于提高速度。然而,这里的主要观点是,在PCL中没有像filterAndAppend(...)这样的方法。

1

票数 1
EN

Stack Overflow用户

发布于 2018-11-19 02:49:39

你原来的点云正在被替换,因为它正是你“告诉”PCL要做的事情,写道:sor.filter(*pointcloud);过滤器方法的参数是“输出云”。您可以传递一个空云,过滤结果将保存到其中。(输入已经通过setInputCloud定义)

因此,您可以将FILTERExamples重写为:

代码语言:javascript
复制
pcl::PointCloud<pcl::PointXYZ>::Ptr FILTREexample(pcl::PointCloud<pcl::PointXYZ>::Ptr pointcloud, pcl::IndicesPtr indices, float x, float y, float z) {
    pcl::PointCloud<pcl::PointXYZ>::Ptr filtered_pointcloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::VoxelGrid<pcl::PointXYZ> sor;
    sor.setInputCloud(pointcloud);
    sor.setIndices(indices);
    sor.setLeafSize(x, y, z);
    sor.filter(*filtered_pointcloud); // No problem :)
    return filtered_pointcloud;
}

而applyExample将只连接clouds

代码语言:javascript
复制
void Octree::applyExample(float x, float y, float z) {    

    ... // no change

    pcl::PointCloud<pcl::PointXYZ>::Ptr filtered_cloud(new pcl::PointCloud<pcl::PointXYZ>);    
    for (it = octree.leaf_begin(); it != it_end; ++it)
    {

        pcl::IndicesPtr indexVector(new vector<int>);
        pcl::octree::OctreeContainerPointIndices& container = it.getLeafContainer();

        container.getPointIndices(*indexVector);
        *filtered_cloud += *FILTREexample(cloud, indexVector, x,y,z);
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53265873

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档