我正在尝试使用 pcl 加载一个大的 ointcloud (5600 万点)。当我加载它时,它给出了正确的大小,但它在 [0,0,0] 处放置了 1900 万个点。我使用云比较和其他软件检查这些点是否位于此处。
这是我的工作代码(它按我的预期编译和运行)。
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/common/io.h>
#include <pcl/common/common.h>
#include <string>
#include <iostream>
#include <fstream>
int main()
{
std::string file_name;
pcl::PointCloud<pcl::PointXYZ>::Ptr pcl_cloud (new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_final (new pcl::PointCloud<pcl::PointXYZ>);
float num_points;
std::cin>>file_name;
int x=0;
pcl::io::loadPCDFile(file_name+".pcd",*pcl_cloud);
for (auto i = 0; i < pcl_cloud->size(); ++i)
{
auto point = pcl_cloud->at(i);
if ((point.x==0)&&(point.y==0)&&(point.z==0)) //(Eigen::seq(0,2))
// {
{
num_points+=1;
continue;
}
}
std::cout<<"pointcloud size: "<<pcl_cloud->size()<<" of which "<<num_points<<" are exactly [0,0,0].\n";
return 0;
}
它返回: 点云大小:56579685,其中 1.67772e+07 正好是 [0,0,0]
点云的第一部分已正确加载。
所以我找到了一个对我有用的解决方法,但仍然不明白出了什么问题。
创建 .pcd 文件时,我首先包含所有可能的字段。 通过创建仅具有 XYZ 尺寸的点云,它起作用了。
当您使用所有可能的字段时,一个点的大小为 92 字节(3 * 4 + 10 * 8,根据您的 PCD 标头)。在写入和读取 PCD 文件期间,数据部分被处理为二进制 blob,该 blob 大小为 92*56579685=5205331020 字节(约 52 亿)。这溢出了 32 位 int(约 21 亿)和 32 位无符号 int(约 43 亿)的值范围。
您可以通过使用更大的索引类型编译 PCL (https://github.com/PointCloudLibrary/pcl/blob/master/cmake/pcl_options.cmake#L96) 或将数据保存为二进制文件来规避此问题PCD而不是ASCII PCD,但也有可能是PCL有bug。
编辑:我也不完全确定问题是在读取时发生还是在写入 PCD 文件时发生。