hwo 使用 pcl 来实现将 3D 点云离散化为 xy 平面上的 2D 网格,而不是使用体素网格?
hwo to use pcl to achieve that discretizing the 3D point cloud into a 2D grid over the xy plane, not use the voxelgrid?
我想在xy平面上将3D点云投影成2D网格,每个网格单元格大小为20cm*20cm,如何有效实现?
不使用VoxelGrid方法,因为我想保留每个点并在下一步处理它们(高斯核每列并使用EM处理每个网格)
您可以使用 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
xy 平面上的 二维网格 是什么意思?还是要z值还是原来的值,还是先把点云投影到XY平面上?
保持 Z 值
如果要保留 Z 值,只需将 leaf size for Z of VoxelGrid
设置为 infinite (或非常大的数字)。
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
。
正如评论中所讨论的那样,您可以通过 OctreePointCloudPointVector
class.
实现您想要的
这是一个如何使用 class:
的例子
#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
查看示例输出
我想在xy平面上将3D点云投影成2D网格,每个网格单元格大小为20cm*20cm,如何有效实现?
不使用VoxelGrid方法,因为我想保留每个点并在下一步处理它们(高斯核每列并使用EM处理每个网格)
您可以使用 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
xy 平面上的 二维网格 是什么意思?还是要z值还是原来的值,还是先把点云投影到XY平面上?
保持 Z 值
如果要保留 Z 值,只需将 leaf size for Z of VoxelGrid
设置为 infinite (或非常大的数字)。
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
。
正如评论中所讨论的那样,您可以通过 OctreePointCloudPointVector
class.
这是一个如何使用 class:
的例子#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
查看示例输出