PCL——数据转换:txt转pcd、bin转pcd

 一、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 
#include 
#include 
#include

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::Ptr cloud(new pcl::PointCloud);
	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 
#include 
#include

#include 
#include 

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::Ptr points(new pcl::PointCloud); //定义点类型为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;
}

 时间久远,忘记参考了哪篇文章,无链接。 

你可能感兴趣的:(PCL点云处理,c++)