项目场景:
用软件对las文件进行标定的时候发现las文件太大打不开
解决方案:
将转化成las文件的pcd切分成几个小块。然后再转化成las文件,最后再将las文件合并。具体操作
思路
pcd转换成pcl::PointCloud<pcl::PointXYZ>::Ptr
的cloud,然后读取cloud, 将cloud 分成小块保存成PCD
依赖的头文件如下:
PCD文件IO操作
由于pcd点云数据格式有它独特的优势,因此本项目基于此继续研究。首先是对点云数据的IO处理,包括从PCD文件读取点云数据和写入点云数据。
#include <iostream>
#include <pcl/io/pcd_io.h> //PCD读写类相关的头文件
#include <pcl/point_types.h> //PCL中支持的点类型头文件
PCD文件的读取操作
法一:使用loadPCDFile
读取milk.pcd文件,若文件不存在,返回错误。此处读取数据采用的是相对路径。
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile<pcl::PointXYZ>("milk.pcd", *cloud) == -1)
{
std::cout << "Cloud reading failed." << std::endl;
return (-1);
}
法二:使用reader
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PCDReader reader;
reader.read("E://box1.pcd", *cloud);
PCD文件的写入操作
法一:使用writer
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PCDWriter writer;
writer.write<pcl::PointXYZ>("test_pcd.pcd", *cloud, false);
法二:使用savePCDFileASCII
pcl::PointCloud<pcl::PointXYZ> cloud;
pcl::io::savePCDFileASCII("test_pcd.pcd",cloud);
参考链接: https://cloud.tencent.com/developer/article/1688130
要用Qt运行代码前,首先要配置相关的依赖库,具体配置可参考下面的链接:
https://blog.youkuaiyun.com/CCCrunner/article/details/118653184?spm=1001.2014.3001.5501
最后上代码:
其中 pointCount_ 是总点云数量
blockNum是分成几块
blockSize是每一块pcd的点云数量
map_test.pcd 是被分割的pcd文件名字
#include <QCoreApplication>
#include <iostream>
#include <pcl/io/pcd_io.h> //PCD读写类相关的头文件
#include <pcl/point_types.h> //PCL中支持的点类型头文件
int main(int argc, char *argv[])
{
int pointCount_ = 0; // PointCloud number
int blockNum = 0;
int blockSize = 1200000;
QCoreApplication a(argc, argv);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ> cloud1;
if (pcl::io::loadPCDFile<pcl::PointXYZ>("map_test.pcd", *cloud) == -1) //Failed to read pcd File
{
std::cout << "Cloud reading failed." << std::endl;
return (-1);
}
else
{
std::cout << "Cloud reading success!" << std::endl;
cloud1 = *cloud;
pointCount_ = cloud1.points.size();
blockNum = pointCount_/blockSize; //Slip groups number
int block_groups[blockNum+1];
int begin = 0;
block_groups[0] = 0;
std::cout<<"block"<<blockNum<<std::endl;
for(size_t i=1;i<=blockNum;i++)
{
block_groups[i] = block_groups[i-1]+1200000;
std::cout<<block_groups[i]<<std::endl;
}
block_groups[blockNum+1] = pointCount_;
pcl::PointCloud<pcl::PointXYZ> tempCloud;
for(size_t i = 0;i<=blockNum+1;i++){
std::cout<<block_groups[i]<<std::endl;
}
for(size_t j = 1;j<=blockNum+1;j++){
tempCloud.height = 1;
tempCloud.width = block_groups[j] - block_groups[j-1];
tempCloud.is_dense = true;
tempCloud.points.resize(tempCloud.width * tempCloud.height);
for(size_t i=block_groups[j-1];i<=block_groups[j];i++){
std::cout<<i<<std::endl;
tempCloud.points[i].x = cloud1.points[i].x;
tempCloud.points[i].y = cloud1.points[i].y;
tempCloud.points[i].z = cloud1.points[i].z;
}
std::string map_name = "map"+std::to_string(j)+".pcd";
std::cout<<"map_name = "<<map_name<<std::endl;
pcl::io::savePCDFileASCII (map_name, tempCloud);
std::cout<<"pcd create"<<std::endl;
}
//cloud = cloud1.makeShared();
}
std::cout<<"cloud1.height = "<<cloud1.height<<std::endl;
std::cout<<"cloud1.width = "<<cloud1.width<<std::endl;
std::cout<<"cloud1.is_dense = "<<cloud1.is_dense<<std::endl;
return a.exec();
}