一、txt转pcd
直接用CloudCompare把las转成pcd在pcl中使用,出不来结果,显示“failed to find match for field ‘intensity”。百度说pcl定义的pcd文件和CloudCompare定义的pcd文件的头文件不一致,导致有些属性读不出来。
尝试las转pcd,网上教程很多,需要先配置liblas库。配置完之后,简单测试了一下打开las文件的代码,报错:std::out_of_range。
那就用简单粗暴一点的方法了。 方法可行,但不是很灵活。如果txt属性对应列发生变化,需要手动改,否则读取的内容就会有误。可以凑合着用。
#include <iostream>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include<pcl/point_types.h>
using namespace std;
using namespace pcl;
//txt转成pcl库可读写的pcd文件
void txt2pcd(string name)
{
//读取txt文件所在路径
string infile = "D:/AAAA/BBBB/CCCC/DDDD/" + name + ".txt";
//打开文件,逐行读取内容
ifstream ifs;
ifs.open(infile, ios::in);
if (ifs.is_open() == -1)
{
cout << "txt文件打开失败" << endl;
}
string line, a;
pcl::PointCloud<pcl::PointXYZI>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZI>);
while (getline(ifs, line))
{
pcl::PointXYZI point;//根据需要,读取xyz及强度信息
std::stringstream ss(line);
ss >> point.x;//1 (找到txt内容中xyz等属性所在列,对应读取
ss >> point.y;//2
ss >> point.z;//3
ss >> a;
ss >> a;
ss >> a;
ss >> a;
ss >> a;//8
ss >> point.intensity;//9
cloud->points.push_back(point);//把读取到的内容存储进自定义的点云中
}
ifs.close();//关闭文件
//保存pcd文件
string outfile = "D:/AAAA/BBBB/CCCC/EEEE/" + name + ".pcd";//文件保存路径
pcl::io::savePCDFileBinary(outfile, *cloud);
}
int main()
{
//如果就一两个文件,且命名在数字上没有规律,是什么名字就写什么名字
txt2pcd("filename");
//如果是批量文件,且命名如001、000001之类的
for (int i = 1; i < 10; i++) {
stringstream ss;
ss << setw(3) << setfill('0') << i;//3,即三位数,'0'即用0填充空位;当i=1,此处ss为'001'
string str;
ss >> str; //将字符流传给 str
txt2pcd(str);
}
system("pause");
return 0;
}
再补充一篇介绍点云属性的文章:LAS点云属性_累了就要打游戏的博客-CSDN博客
二、bin转pcd
因为有下载过KITTI数据集使用,里面原始数据是bin格式,需要转成pcd。
#define BOOST_TYPEOF_EMULATION //这句是为了解决一个错误,具体什么错误忘了
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include<pcl/point_types.h>
#include <iostream>
#include <fstream>
using namespace pcl;
using namespace std;
void bin2pcd(string name)
{
//读取bin文件的路径
string infile = "D:/AAAA/BBBB/CCCC/DDDD/" + name + ".bin";
///保存pcd结果的文件夹所在路径
string outfile = "D:/AAAA/BBBB/CCCC/EEEE/" + name + ".pcd";
//读取bin格式的点云数据
fstream input(infile.c_str(), ios::in | ios::binary);
if (!input.good()) {
cerr << "Could not read file: " << infile << endl;
exit(EXIT_FAILURE);
}
input.seekg(0, ios::beg);
pcl::PointCloud<PointXYZI>::Ptr points(new pcl::PointCloud<PointXYZI>); //定义点类型为XYZI的点云容器
int i;
for (i = 0; input.good() && !input.eof(); i++) {
PointXYZI point;
input.read((char*)&point.x, 3 * sizeof(float)); //转存XYZ值
input.read((char*)&point.intensity, sizeof(float));//转存intensity值
points->push_back(point);//将读到的点存入自定义的点云容器points中
}
input.close(); //读取结束,转存结束
pcl::io::savePCDFileBinary(outfile, *points);//保存pcd文件
cout << "Read KTTI point cloud with " << i << " points, writing to " << outfile << endl;
}
int main()
{
//如果就一两个文件,且命名在数字上没有规律,是什么名字就写什么名字
bin2pcd("filename");
//如果是批量文件,且命名如001、000001之类的
for (int i = 0; i < 4541; ; i++) {
stringstream ss;
ss << setw(6) << setfill('0') << i;//6,即六位数,'0'即用0填充空位;当i=1,此处ss为'000001'
string str;
ss >> str; //将字符流传给 str
bin2pcd(str);
}
system("pause");
return 0;
}
时间久远,忘记参考了哪篇文章,无链接。