[pcl::PCDReader::read] Number of points read (3643177) is different than expected (7335701)

本文介绍了解决因进程强制退出导致的PCD文件点数不一致的问题,提供了两种解决方案:一是手动修改PCD文件中的点数字段;二是调整ROS进程超时设置。

[pcl::PCDReader::read] Number of points read (3643177) is different than expected (7335701) couldn’t load the pcd file

引子

  lego-loam和lio-sam在跑完建图之后,可以选择是否导出特征点地图和fullMap的pcd文件。lego-loam导出pcd文件的代码附在最后(有所改动,详情可参考源码),pcd文件最后存到/tmp目录下。该段代码是放在visualizeMapThread中的,前面有一个ros::ok的循环。当ctrl+c结束后,开始执行后面的导出pcd程序,但如果在一定时间内没有执行完,进程强制退出,窗口抛出"escalating to SIGTERM"错误。此时存储的pcd文件可能是不完全的,当使用pcl::io::loadPCDFile或者pcl::PCDReader::read读取的时候,可能会报"Number of points read (3643177) is different than expected (7335701)" 错误,这是由于pcl::PointCloud的field中记录的点数和实际点数不一致引起的,可以通过以下两种方式解决:

1、修改field —— 使用文本编辑软件打开pcd文件,直接修改field中的WIDTH和POINTS的数值。该方法具有一般性,当然还是应该查一下为什么点数会不一致。下图是使用vscode打开Xpcd文件效果截图。

自己使用vscode打开个pcd文件试试
2、针对"escalating to SIGTERM"1引起的点云数目不一致问题,修改/opt/ros/
kinetic(ros版本)/lib/python2.7/dist-package/roslaunch/nodeprocess.py文件中的"_TIMEOUT_SIGINT = 15.0 #seconds"为自己期望的运行时间,从而保证实际点数和field中记录的值相同。当然,这只针对由"escalating to SIGTERM"引起的点数不一致问题,不具有一般性。
请参考/opt/ros/kinetic(ros版本)/lib/python2.7/dist-package/roslaunch/nodeprocess.py

    void visualizeGlobalMapThread() {
   
   
        ros::Rate rate(0.2);
        while (ros::ok()){
   
   
            rate.sleep();
            publishGlobalMap();
        }
	    std::cout << "save point cloud" << std::endl;
        
<think>好的,用户遇到了一个关于PCL读取PCD文件时的错误:读取的点数(31178533)与预期的(85169588)不一致。我需要分析可能的原因,并给出解决方案。首先,用户可能是在处理一个非常大的点云文件,这种情况下的常见问题可能包括文件损坏、内存不足或PCL版本问题。 首先,考虑文件是否损坏。用户可能在生成或传输PCD文件时出现了错误,导致文件不完整或格式错误。建议用户使用PCLPCD检查工具或可视化工具如CloudCompare来验证文件完整性。 其次,内存不足的问题。用户尝试读取的点云非常大(超过8500万点),这可能超出了系统可用内存。需要确认系统是否有足够的RAM,并考虑使用分块读取或降采样处理。 另外,PCL版本可能存在兼容性问题。不同版本的PCLPCD文件的支持可能不同,特别是如果文件是用旧版本生成的,可能需要升级PCL库。 用户可能还希望优化代码,比如使用指针或分块处理来减少内存压力。同时,建议用户检查文件是否确实包含预期数量的点,可能通过其他软件验证。 最后,可能需要考虑使用更高效的点云格式如PLY或LAS,或者进行数据压缩,以减少内存占用。用户可能需要调整PCL的配置参数,或者在读取时设置最大点数限制,以避免内存溢出。</think>该错误提示表明PCL读取PCD文件时检测到实际点数与文件头声明的点数不一致,常见原因及解决方案如下: ```cpp #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/point_cloud.h> #include <pcl/console/print.h> int main(int argc, char** argv) { pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); // 使用try-catch捕获异常 try { if (pcl::io::loadPCDFile("input.pcd", *cloud) == -1) { PCL_ERROR("Couldn't read file input.pcd\n"); return (-1); } pcl::console::print_info("Loaded %d points from PCD file\n", cloud->size()); } catch (const pcl::IOException& e) { pcl::console::print_error("PCL IO Exception: %s\n", e.what()); // 建议操作:检查文件完整性 } // 验证点数一致性 FILE* fp = fopen("input.pcd", "r"); if (!fp) { pcl::console::print_error("Failed to open file for validation\n"); return -1; } char line[1024]; int expected_points = 0; while (fgets(line, sizeof(line), fp)) { if (strncmp(line, "POINTS ", 7) == 0) { sscanf(line + 7, "%d", &expected_points); break; } } fclose(fp); pcl::console::print_info("Header claims: %d points\n", expected_points); pcl::console::print_info("Actual loaded: %d points\n", cloud->size()); return 0; } ``` ### 主要解决方案: 1. **文件修复** ```bash # 使用PCL工具修复PCD文件 pcl_pcd2pcd input.pcd fixed.pcd ``` 2. **内存优化读取** ```cpp // 分块读取大型点云 pcl::PCDReader reader; reader.setCloudPointer(cloud); reader.read("input.pcd", 0, 1000000); // 读取前100万点 ``` 3. **格式转换建议** ```cpp // 转换为更稳定的PLY格式 pcl::PolygonMesh mesh; pcl::io::loadPCDFile("input.pcd", mesh); pcl::io::savePLYFile("output.ply", mesh); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值