直接用CloudCompare把las转成pcd在pcl中使用,出不来结果,显示“failed to find match for field ‘intensity”。百度说pcl定义的pcd文件和CloudCompare定义的pcd文件的头文件不一致,导致有些属性读不出来。
尝试las转pcd,网上教程很多,需要先配置liblas库。配置完之后,简单测试了一下打开las文件的代码,就报错了:std::out_of_range。不是很理解哪里出了问题,也不能一直卡在这,再换一个转换方法。

txt转pcd
txt格式的文件没什么花里胡哨的东西,直接在CloudCompare打开las格式数据,转换成txt。转之前可以勾选把title加上,就能清楚哪列是什么属性,下图前三列分别是xyz。源数据xy是真实直角坐标系的值,但是在CC里打开之后都做了统一的偏移,所以这里的值很小。


接下来在pcl中读txt的内容,有选择的取出需要的属性值,保存到点云中,再保存为pcd文件。 代码如下:
#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;
}本方法可行,但不是很灵活。如果txt属性对应列发生变化,需要手动改,否则读取的内容就会有误。目前凑合着用。
再补充一篇介绍点云属性的文章:LAS点云属性_累了就要打游戏的博客-CSDN博客
版权声明:本文为QomoL_原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。