Je souhaite projeter le nuage de points 3D dans une grille 2D sur le plan xy, la taille de chaque cellule de la grille est de 20 cm * 20 cm, comment y parvenir efficacement?
N'utilisez PAS la méthode VoxelGrid, car je veux conserver chaque point et les traiter à l'étape suivante (noyau gaussien chaque colonne et utiliser EM pour gérer chaque grille)
3 Réponses :
Vous pouvez y parvenir en utilisant https://github.com/daavoo/pyntcloud avec ce qui suit code:
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]
Vous pouvez en savoir plus sur VoxelGrid ici:
https://github.com/daavoo/pyntcloud/blob/master/examples/%5Bstructures%5D%20VoxelGrid.ipynb p >
Que voulez-vous dire par grille 2D sur le plan xy ? Voulez-vous toujours que la valeur z soit la valeur d'origine, ou voulez-vous d'abord projeter le nuage de points sur le plan XY?
Si vous souhaitez conserver les valeurs Z, il suffit de définir la taille de la feuille pour Z de VoxelGrid
à l'infini (ou un très grand nombre).
for(auto& pt : cloud) pt.z = 0.0f;
Projeter un nuage sur le plan XY n'est rien d'autre que de définir le Valeur Z pour chaque point à 0
pcl::VoxelGrid<pcl::PCLPointCloud2> sor; sor.setInputCloud (cloud); sor.setLeafSize (0.01f, 0.01f, 100000.0f); sor.filter (*cloud_filtered);
Vous pouvez maintenant faire un VoxelGrid
normal sur le nuage de points projeté.
d'après ma compréhension, VoxelGrid est une méthode pour réaliser un sous-échantillonnage, ce qui signifie chaque point de sortie de la grille d'entrée. Je veux projeter le nuage de points d'origine sur le plan xy et le pixelliser, chaque taille de grille est de 20 cm * 20 cm, et conserver chaque point du nuage de points, pas sous-échantillonner
OK je vois. Dans ce cas, je recommanderais d'utiliser OctreePointCloudVectorPoint . Projetez d'abord votre nuage de points d'entrée sur le plan XY, utilisez ce nuage de points projeté comme entrée pour l'Octree. Ensuite, vous aurez les indices des points du nuage de points d'entrée dans chacun des voxels.
ouais, je réalise en fait la projection sur le plan xy, mais je suis confus par la pixellisation. ma méthode de projection est pcl :: ModelCoefficients :: Ptr coefficients (new pcl :: ModelCoefficients ()); coefficients-> values.resize (4); coefficients-> valeurs [0] = 0; coefficients-> valeurs [1] = 0; coefficients-> valeurs [2] = 1; coefficients-> valeurs [3] = 0;
merci pour votre réponse, je recherche effectivement la méthode Octree, je suis confus par quelque chose. La première chose est de savoir si le voxel d'Octree est vide à l'intérieur mais représente simplement un pixel sur un plan 2D. Le deuxième problème est que si je veux connaître la répartition à l'intérieur de la grille, que dois-je faire?
@WanEthan je vais vous montrer comment réaliser ce que vous voulez dans une réponse séparée.
Comme indiqué dans les commentaires, vous pouvez obtenir ce que vous voulez avec la classe OctreePointCloudPointVector
.
Voici un exemple d'utilisation de la classe:
#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); } }
salut, serkan. J'exécute le code, mais j'étais confus que je ne trouve pas les fichiers de résultats finaux (le nom de leaf_number) lorsque j'utilise Visual Studio.
Les fichiers seront écrits dans le chemin, à partir duquel VS exécute le programme. Vous pouvez toujours changer le chemin vers un chemin absolu dans pcl :: io :: savePCDFileBinary ()
.
Bienvenue dans Stack Overflow! Veuillez consulter rédiger la question parfaite pour vous aider à posez une bonne question, et obtenez ainsi une bonne réponse.
Veuillez consulter: stackoverflow.com/a/49749230/6812182