PCL——数据转换: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转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版权协议,转载请附上原文出处链接和本声明。