为什么要使用pcl来实现将3D点云离散化到xy平面上的2D网格中,而不使用voxelgrid?

时间:2019-01-10 15:38:45

标签: point-cloud-library point-clouds

我想将3D点云投影到xy平面上的2D网格中,每个网格单元大小为20cm * 20cm,如何有效地实现呢?

不要使用VoxelGrid方法,因为我想保留每个点并在下一步中处理它们(高斯内核每列并使用EM处理每个网格)

3 个答案:

答案 0 :(得分:0)

您可以使用https://github.com/daavoo/pyntcloud和以下代码来实现此目的:

from pyntcloud import PyntCloud

cloud = PyntCloud.from_file("some_cloud.ply")
# 0.2 asumming your point cloud units are meters
voxelgrid_id = cloud.add_structure("voxelgrid", size_x=0.2, size_y=0.2)

voxelgrid = cloud.structures[voxelgrid_id]

您可以在此处了解有关VoxelGrid的更多信息:

https://github.com/daavoo/pyntcloud/blob/master/examples/%5Bstructures%5D%20VoxelGrid.ipynb

答案 1 :(得分:0)

在xy平面上的 2D网格是什么意思?您是否仍希望z值是原始值,还是要先将点云投影到XY平面?

保持Z值

如果要保留Z值,只需将VoxelGrid Z 叶子大小设置为无限(或很大)。

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

首先将云投影到XY平面

将云投影到 XY平面无非就是将每个点的 Z值设置为 0

for(auto& pt : cloud)
    pt.z = 0.0f;

现在,您可以在投影点云上进行常规VoxelGrid了。

答案 2 :(得分:0)

如评论中所述,您可以使用OctreePointCloudPointVector类来实现所需的目标。

以下是使用该类的示例:

#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl/octree/octree_pointcloud_pointvector.h>

using Cloud    = pcl::PointCloud<pcl::PointXYZ>;
using CloudPtr = Cloud::Ptr;

using OctreeT = pcl::octree::OctreePointCloudPointVector<pcl::PointXYZ>;

int main(int argc, char** argv)
{
    if(argc < 2)
        return 1;

    // load cloud
    CloudPtr cloud(new Cloud);
    pcl::io::loadPCDFile(argv[1], *cloud);

    CloudPtr cloud_projected(new Cloud(*cloud));
    // project to XY plane
    for(auto& pt : *cloud_projected)
        pt.z = 0.0f;

    // create octree, set resolution to 20cm
    OctreeT octree(0.2);
    octree.setInputCloud(cloud_projected);
    octree.addPointsFromInputCloud();

    // we gonna store the indices of the octree leafs here
    std::vector<std::vector<int>> indices_vec;
    indices_vec.reserve(octree.getLeafCount());

    // traverse the octree leafs and store the indices
    const auto it_end = octree.leaf_depth_end();
    for(auto it = octree.leaf_depth_begin(); it != it_end; ++it)
    {
        auto leaf = it.getLeafContainer();
        std::vector<int> indices; 
        leaf.getPointIndices(indices);
        indices_vec.push_back(indices);
    }

    // save leafs to file
    int cnt = 0;
    for(const auto indices : indices_vec)
    {
        Cloud leaf(*cloud, indices);
        pcl::io::savePCDFileBinary("leaf_" + std::to_string(cnt++) + ".pcd", leaf);
    }
}

您可以通过调用pcl_viewer来查看输出:

  

pcl_viewer leaf _ *。pcd

查看示例输出sample output