txt点云转pcd点云并显示

将txt格式的点云文件转化为pcd格式点云并进行显示!

一、核心函数:

默认设置分割符为空格,可以设置为逗号或分号。可以适当修改,读取坐标之外的反射强度、颜色等其他信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
bool readTxtFile(const string &fileName, const char tag, const PointCloudT::Ptr &pointCloud)
{
cout << "reading file start..... " << endl;
ifstream fin(fileName);
string linestr;
vector<PointT> myPoint;
while (getline(fin, linestr))
{
vector<string> strvec;
string s;
stringstream ss(linestr);
while (getline(ss, s, tag))
{
strvec.push_back(s);
}
if (strvec.size() < 3){
cout << "格式不支持" << endl;
return false;
}
PointT p;
p.x = stod(strvec[0]);
p.y = stod(strvec[1]);
p.z = stod(strvec[2]);
myPoint.push_back(p);
}
fin.close();

//转换成pcd
pointCloud->width = (int)myPoint.size();
pointCloud->height = 1;
pointCloud->is_dense = false;
pointCloud->points.resize(pointCloud->width * pointCloud->height);
for (int i = 0; i < myPoint.size(); i++)
{
pointCloud->points[i].x = myPoint[i].x;
pointCloud->points[i].y = myPoint[i].y;
pointCloud->points[i].z = myPoint[i].z;
}
cout << "reading file finished! " << endl;
cout << "There are " << pointCloud->points.size() << " points!" << endl;
return true;
}

需要注意的是,下列写法存在问题,显示点云时没问题,但输出保存时会出现异常。猜测是点云没有设置宽高与有序无需属性导致,求大神解惑。

1
2
3
4
5
PointT p;
p.x = stod(strvec[0]);
p.y = stod(strvec[1]);
p.z = stod(strvec[2]);
pointCloud.push_back(p);

二、示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <iostream>
#include <fstream>
#include <strstream>
#include <vector>
#include <pcl/io/pcd_io.h> //文件输入输出
#include <pcl/point_types.h> //点类型相关定义
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/visualization/pcl_visualizer.h>

using namespace std;

typedef pcl::PointXYZ PointT;
typedef pcl::PointCloud<PointT> PointCloudT;


bool readTxtFile(const string &fileName, const char tag, const PointCloudT::Ptr &pointCloud)
{
cout << "reading file start..... " << endl;
ifstream fin(fileName);
string linestr;
vector<PointT> myPoint;
while (getline(fin, linestr))
{
vector<string> strvec;
string s;
stringstream ss(linestr);
while (getline(ss, s, tag))
{
strvec.push_back(s);
}
if (strvec.size() < 3){
cout << "格式不支持" << endl;
return false;
}
PointT p;
p.x = stod(strvec[0]);
p.y = stod(strvec[1]);
p.z = stod(strvec[2]);
myPoint.push_back(p);
}
fin.close();

//转换成pcd
pointCloud->width = (int)myPoint.size();
pointCloud->height = 1;
pointCloud->is_dense = false;
pointCloud->points.resize(pointCloud->width * pointCloud->height);
for (int i = 0; i < myPoint.size(); i++)
{
pointCloud->points[i].x = myPoint[i].x;
pointCloud->points[i].y = myPoint[i].y;
pointCloud->points[i].z = myPoint[i].z;
}
cout << "reading file finished! " << endl;
cout << "There are " << pointCloud->points.size() << " points!" << endl;
return true;
}


int main()
{
//1.读取点云
PointCloudT::Ptr cloud(new PointCloudT);
readTxtFile("data1.txt",' ',cloud);

//2.显示点云
pcl::visualization::PCLVisualizer viewer("cloud viewer");
viewer.addPointCloud<PointT>(cloud, "sample");


while (!viewer.wasStopped())
{
viewer.spinOnce();
}

//3.点云输出
pcl::PCDWriter writer;
writer.writeASCII<PointT>("demo.pcd", *cloud);


system("pause");
return 0;
}

三、运行结果:

txt点云读取结果

四、备注:

当点云原始坐标精度较高时,转换为pcd格式容易丢失精度。从上图可以看出,点云显示效果已然失真,扫描线变成了斜线而不是直线!因此,当原始点云坐标数字有效位数过多时,应该进行平移,减少坐标有效位数。

-------------本文结束感谢您的阅读-------------