版权声明:版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_22170875/article/details/84729574
1.pcd文件格式
2.C++源码
读取思路:连续读取前11行,获得pcd文件信息头,取得点云存储方式(ascii或者binary)和点云数量、点云格式(XYZ,XYZI....)等关键信息,然后按行依次读取坐标数据即可。
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <vector>
struct PointXYZ
{
double x, y, z;
};
/*
Author:chd_ayj
Date:2018-6-8
Description: read .PCD file
*/
//读取pcd点云文件
void readPCDfile(const std::string finname, std::vector<PointXYZ>& points, const std::string foutname)
{
std::ifstream fin(finname);
if (fin.bad()){
std::cout << "打开文件失败!" << std::endl;
return;
}
char s[11][1024]; //存储Header
int Points_Num; //点数量
std::string data_columns_type; //列数: X Y Z
std::string data_type; //点坐标存储方式(ascii或者binary)
std::vector<PointXYZ> cloud;
//连续读取Header行数
std::cout << "start to read file header....." << std::endl;
std::cout << "file header: " << std::endl;
for (int i = 0; i < 11; ++i){
fin.getline(s[i], 1024);
//std::cout << "第" << i + 1 << "行:" << s[i] << std::endl;
std::cout << s[i] << std::endl;
//FIELDS x y z rgb
if (i == 2){
std::string s2 = s[2];
size_t pos = s2.find("FIELDS");
size_t size = s2.size();
data_columns_type = s2.substr(pos + 7, size);
//std::cout << "data_columns_type:" << data_columns_type << std::endl;
}
//POINTS xxx
if (i == 9){
std::string s9 = s[9], Points_Str;
size_t pos = s9.find("POINTS");
size_t size = s9.size();
Points_Str = s9.substr(pos + 7, size);
Points_Num = atoi(Points_Str.c_str());
//std::cout << "Points:" << std::Points_Num << endl;
}
//DATA ascii或者binary
if (i == 10){
std::string s10 = s[10], DATA_SIZE;
size_t pos = s10.find("DATA");
size_t size = s10.size();
data_type = s10.substr(pos + 5, size);
//std::cout << "data_type:" << data_type << std::endl;
}
}
std::cout << std::endl;
std::cout << "start to read point ....." << std::endl;
PointXYZ p;
if ((data_columns_type == "x y z") && (data_type == "ascii")){
//读取点坐标记录
while (!fin.eof()){
fin >> p.x >> p.y >> p.z;
if (fin.peek() == EOF){
break;
}
cloud.push_back(p);
}
}else{
std::cout << "data_type = binary, read failed!" << std::endl;
}
////////////////////////////////////////////////////////////
//点坐标输出txt文本
std::cout << "start to write point to txt....." << std::endl;
std::ofstream out(foutname);
for (size_t i = 0; i < points.size(); ++i)
{
out << std::setiosflags(std::ios::fixed) << std::setprecision(7)
<< points.at(i).x << " "
<< points.at(i).y << " "
<< points.at(i).z << std::endl;
}
std::cout << "write point to txt finished!" << std::endl;
}
int main()
{
std::string finname = "ascii_pcd.pcd";
std::string foutame = "ascii_pcd.txt";
std::vector<PointXYZ> points;
readPCDfile(finname, points, foutame);
system("pause");
return 0;
}
2.运行结果:
3.总结
- string中的find()函数,功能:查找第一次出现的目标字符串,如果存在则返回查找到的第一个字符的索引,否则返回-1。
- string中的substr(pos, n)函数,功能:返回一个string,包含pos位置开始的n个字符的拷贝(pos的默认值是0,n的默认值是s.size() - pos,即不加参数会默认拷贝整个s)。
- string s.c_str()函数,功能:把string转化成const char*,返回一个指向正规C字符串的指针常量。
- int atoi(const char *nptr),功能:字符串转换成整型数。