1. 读取文件

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
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>

int main(int argc, char** argv){
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);

// 打开点文件
if (pcl::io::loadPCDFile<pcl::PointXYZ>("../test.pcd", *cloud) == -1){
PCL_ERROR("Couldn't read file point_cloud.pcd \n");
return (-1);
}

// 默认就是二进制块读取,转换为模块化PointCloud
std::cout << "Loaded "
<< cloud->width * cloud->height
<< " data points from point_cloud.pcd with the following fields: "
<< std::endl;

for (size_t i = 0; i < cloud->points.size(); ++i){
std::cout << " " << cloud->points[i].x
<< " " << cloud->points[i].y
<< " " << cloud->points[i].z << std::endl;

}
}

2. 保存数据

保存数据总共两种方式,

一种是保存成ascii格式,一种是保存成二进制格式

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
#include<pcl/io/pcd_io.h>

using namespace std;

int main(){
// 从硬盘中读取点云文件
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PCDReader reader; // 定义点云读取对象
if (reader.read("../test.pcd", *cloud_in) < 0) {
PCL_ERROR("Couldn't read file test.pcd \n");
system("pause");
return -1;
}
cout<< "->loaded " << cloud_in->points.size() << " data points from test.pcd" << endl;

// --------------------------------------------------------------------------------------
// 点云投影到XOY平面
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_projected(new pcl::PointCloud<pcl::PointXYZ>);

// 定一个输出参数
cloud_projected->width = cloud_in->width;
cloud_projected->height = 1;
cloud_projected->is_dense = true;
cloud_projected->points.resize(cloud_in->points.size());

for (size_t i = 0; i < cloud_in->points.size(); i++){
cloud_projected->points[i].x = cloud_in->points[i].x;
cloud_projected->points[i].y = cloud_in->points[i].y;
cloud_projected->points[i].z = 0;
}

// ---------------------------------------------------------------------------------------
// 将投影后的点云保存到文件

// 方法1:保存为ASCII格式
if (!cloud_projected->empty()){
pcl::io::savePCDFileASCII("projected.pcd", *cloud_projected);
cout<< "->Saved " << cloud_projected->points.size() << " data points to projected.pcd" << endl;
} else{
PCL_ERROR("Couldn't save projected.pcd \n");
system("pause");
return -1;
}
// 方法2:保存为二进制格式
if (!cloud_projected->empty()){
pcl::io::savePCDFileBinary("projected.pcd", *cloud_projected);
cout<< "->Saved " << cloud_projected->points.size() << " data points to projected.pcd" << endl;
}else{
PCL_ERROR("Couldn't save projected.pcd \n");
system("pause");
return -1;
}

return 0;

}

3. 点云连接

编译运行

1
2
3
4
5
6
mkdir build
cd build
cmake ..
make
./io -f
./io -p

CMakeLists.txt

1
2
3
4
5
6
7
8
9
10
11
12
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)

project(io)

find_package(PCL 1.11 REQUIRED)

include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})

add_executable (io m3.cpp)
target_link_libraries (io ${PCL_LIBRARIES})

代码:

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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>

int main(int argc, char** argv){
std::cout << "argc: " << argc << std::endl;
std::cout << "argv: " << argv[1] << std::endl;
if (argc != 2){
std::cerr << "please specify command line arg '-f' or '-p' " << std::endl;
exit(0);
}

pcl::PointCloud<pcl::PointXYZ> cloud_a,cloud_b,cloud_c;
pcl::PointCloud<pcl::Normal> n_cloud_b;
pcl::PointCloud<pcl::PointNormal> p_n_cloud_c;

// 创建点云
cloud_a.width = 5;
cloud_a.height = cloud_b.height = n_cloud_b.height = 1;
cloud_a.points.resize(cloud_a.width * cloud_a.height); // 总数

// 判断是否连接为a+b=c
if (strcmp(argv[1],"-p") == 0){
cloud_b.width = 3;
cloud_b.points.resize(cloud_b.width * cloud_b.height);
}else{
n_cloud_b.width = 5; // 如果是连接XYZ与normal则生成5个法线
n_cloud_b.points.resize(n_cloud_b.width * n_cloud_b.height);
}

// --------------------------------------------------------------------
// 填充点云
for (size_t i = 0; i < cloud_a.points.size(); ++i){
cloud_a.points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
cloud_a.points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
cloud_a.points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
}

if (strcmp(argv[1],"-p") == 0){
for (size_t i = 0; i < cloud_b.points.size(); ++i){
cloud_b.points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
cloud_b.points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
cloud_b.points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
}
}else{
for (size_t i = 0; i < n_cloud_b.points.size(); ++i){
n_cloud_b.points[i].normal[0] = 1024 * rand() / (RAND_MAX + 1.0f);
n_cloud_b.points[i].normal[1] = 1024 * rand() / (RAND_MAX + 1.0f);
n_cloud_b.points[i].normal[2] = 1024 * rand() / (RAND_MAX + 1.0f);
}
}

// --------------------------------------------------------------------
// 输出 A
std::cerr << "Cloud A: " << std::endl;
for (size_t i = 0; i < cloud_a.points.size(); ++i){
std::cerr << " " << cloud_a.points[i].x
<< " " << cloud_a.points[i].y
<< " " << cloud_a.points[i].z << std::endl;
}
// 输出 B
std::cerr << "Cloud B: " << std::endl;
if (strcmp(argv[1],"-p") == 0){
for (size_t i = 0; i < cloud_b.points.size(); ++i){
std::cerr << " " << cloud_b.points[i].x
<< " " << cloud_b.points[i].y
<< " " << cloud_b.points[i].z << std::endl;
}
}else{
for (size_t i = 0; i < n_cloud_b.points.size(); ++i){
std::cerr << " " << n_cloud_b.points[i].normal[0]
<< " " << n_cloud_b.points[i].normal[1]
<< " " << n_cloud_b.points[i].normal[2] << std::endl;
}
}

// -----------------------------------------------------------
// 连接
if (strcmp(argv[1],"-p") == 0){
cloud_c = cloud_a;
cloud_c += cloud_b; // a+b = c
std::cerr << "Cloud C: " << std::endl;
for (size_t i = 0; i < cloud_c.points.size(); ++i){
std::cerr << " " << cloud_c.points[i].x
<< " " << cloud_c.points[i].y
<< " " << cloud_c.points[i].z << std::endl;
}
}else{
pcl::concatenateFields(cloud_a, n_cloud_b, p_n_cloud_c); // 连接字段
std::cerr << "Cloud C: " << std::endl;
for (size_t i = 0; i < p_n_cloud_c.points.size(); ++i){
std::cerr << " " << p_n_cloud_c.points[i].normal[0]
<< " " << p_n_cloud_c.points[i].normal[1]
<< " " << p_n_cloud_c.points[i].normal[2] << std::endl;
}
}

return 0;

}