Как использовать pcl для достижения того, чтобы дискретизировать трехмерное облако точек в двумерную сетку над плоскостью xy, не использовать вокселгрид? - PullRequest
0 голосов
/ 10 января 2019

Я хочу спроецировать трехмерное облако точек на двумерную сетку над плоскостью xy, размер каждой ячейки сетки составляет 20 см * 20 см, как этого добиться эффективно?

НЕ использовать метод VoxelGrid, потому что я хочу сохранить каждую точку и разобраться с ними на следующем шаге (ядро Гаусса в каждом столбце и использовать EM для работы с каждой сеткой)

Ответы [ 3 ]

0 голосов
/ 17 января 2019

Что вы имеете в виду под 2D сеткой над плоскостью xy ? Вы по-прежнему хотите, чтобы значение z было исходным, или вы сначала хотите спроецировать облако точек на плоскость XY?

Сохранить значение Z

Если вы хотите сохранить значения Z, просто установите размер листа для Z из VoxelGrid в бесконечное (или очень большое число).

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 на облаке проецируемых точек.

0 голосов
/ 19 января 2019

Как обсуждалось в комментариях, вы можете достичь того, что вы хотите с 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

0 голосов
/ 13 января 2019

Вы можете достичь этого, используя 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

...