将txt格式(XYZRGB)点云转换为pcd格式,最后可视化。
txt文件格式如下:
conferenceRoom.txt:(此文件是一个会议室的点云txt文件,6个值依次是XYZ坐标及RGB值,下面截取了其中一部分)
-15.609 39.505 2.214 71 64 54
-15.634 39.518 2.198 68 64 52
-15.622 39.514 2.195 70 61 52
-15.621 39.510 2.215 72 65 55
-15.606 39.505 2.211 71 63 52
-15.657 39.524 2.213 76 70 58
-15.549 39.484 2.206 63 53 44
-15.639 39.520 2.197 70 64 52
-15.562 39.489 2.206 68 58 48
-15.542 39.481 2.206 63 53 44
转换为pcd(pointXYZRGB)格式,效果如下:
# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z rgb
SIZE 4 4 4 4
TYPE F F F U
COUNT 1 1 1 1
WIDTH 1136617
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 1136617
DATA ascii
-15.609 39.505001 2.214 4282859574
-15.634 39.518002 2.198 4282662964
-15.622 39.514 2.1949999 4282793268
-15.621 39.509998 2.2149999 4282925367
-15.606 39.505001 2.211 4282859316
-15.657 39.523998 2.2130001 4283188794
-15.549 39.484001 2.2060001 4282332460
-15.639 39.52 2.197 4282794036
-15.562 39.488998 2.2060001 4282661424
-15.542 39.480999 2.2060001 4282332460
cpp代码:(test3.cpp)
#include <iostream>
#include <string>
#include <pcl/io/pcd_io.h>
int main(int argc, char const *argv[])
{
//-------------------------- 1、输入文件路径并打开 ----------------------------
std::string input_file_path = "../conferenceRoom.txt";
// std::string output_file_path = "conferenceRoom.pcd";
//创建 ifstream 对象并打开文件
std::ifstream input_file(input_file_path);
//检查文件是否成功打开
if(!input_file.is_open()){
// std::cerr <<
std::cerr << "文件打开失败!\a" << std::endl;
return 1; // 返回非零值表示程序发生错误
}
//-------------------------- 2、读取点信息,并转为pcd点云 ----------------------------
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
std::string p_i; //每一行对应的点 p_i
//逐行遍历txt
while (getline(input_file, p_i))
{
//cout << p_i << endl; //打印每一行(点)
// char separator = ' '; //空格分割符
std::stringstream ss(p_i); //点云赋值
pcl::PointXYZRGB temp_pt;
double r, g, b;//临时存放rgb,再将rgb依次赋值给temp_pt的rgb
ss >> temp_pt.x;
ss >> temp_pt.y;
ss >> temp_pt.z;
ss >> r;
ss >> g;
ss >> b;
temp_pt.r = r;
temp_pt.g = g;
temp_pt.b = b;
//cout << temp_pt << endl; //打印转换后的点
cloud->push_back(temp_pt);
}
if (!cloud->empty())
{
// pcl::io::savePCDFileBinary("D:/CSDN_CODE/data/0421_2_txt2pcd/threeTrees_XYZRGB.pcd", *cloud);
pcl::io::savePCDFileASCII("conferenceRoom.pcd", *cloud);
std::cout << "保存pcd点数:" << cloud->points.size() << std::endl;
}
else
{
PCL_ERROR("\a保存点云为空!\n");
system("pause");
}
return 0;
}
CMakeLists.txt文件:
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(cloud_viewer)
find_package(PCL 1.7 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable(test3 test3.cpp)
target_link_libraries(test3 ${PCL_LIBRARIES})
准备好各部分代码后,在集成终端中新建build文件,依次执行cmake ..指令,make指令,./test指令。
$ mkdir build
$ cd build
$ cmake ..
$ make
$ ./test3
执行上述指令可以在build文件夹下生成conferenceRoom.pcd文件
最后在集成终端中执行:
pcl_viewer conferenceRoom.pcd
即可显示点云。
效果如下:
————————————————最后是gpt给出的代码解释———————————————
这段代码是一个简单的C++程序,它从一个文本文件中读取点云数据,将其转换为PCL(Point Cloud Library)中的 `pcl::PointCloud<pcl::PointXYZRGB>` 类型的点云对象,并将该点云保存为PCD(Point Cloud Data)文件。
逐步解释代码:
1. 头文件引用:
#include <iostream>
#include <string>
#include <pcl/io/pcd_io.h>
这里引用了一些C++标准库的头文件,以及PCL库的`pcd_io.h`头文件,后者包含了用于读写PCD文件的相关功能。
2. 文件路径定义:
std::string input_file_path = "../conferenceRoom.txt";
定义了输入文件的路径,即存储点云数据的文本文件的路径。
3. 文件打开:
std::ifstream input_file(input_file_path);
创建一个 `std::ifstream` 对象 `input_file` 并打开输入文件。如果文件无法打开,程序输出错误信息并返回1。
4. 点云对象的创建:
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
创建一个PCL点云对象,类型为 `pcl::PointXYZRGB`,并使用智能指针进行管理。
5. 逐行读取txt文件并转换为点云:
while (getline(input_file, p_i))
{
std::stringstream ss(p_i); // 创建字符串流对象,用于解析当前行的数据
pcl::PointXYZRGB temp_pt;
double r, g, b; // 临时存放rgb,再将rgb依次赋值给temp_pt的rgb
ss >> temp_pt.x;
ss >> temp_pt.y;
ss >> temp_pt.z;
ss >> r;
ss >> g;
ss >> b;
temp_pt.r = r;
temp_pt.g = g;
temp_pt.b = b;
cloud->push_back(temp_pt); // 将当前点加入点云对象
}
逐行读取输入文件中的数据,每行的数据包括x、y、z以及RGB颜色信息。将这些数据逐个读取,并将它们赋值给 `pcl::PointXYZRGB` 类型的 `temp_pt`,然后将 `temp_pt` 添加到点云对象 `cloud` 中。
6. 保存点云为PCD文件:
if (!cloud->empty())
{
pcl::io::savePCDFileASCII("conferenceRoom.pcd", *cloud);
std::cout << "保存pcd点数:" << cloud->points.size() << std::endl;
}
else
{
PCL_ERROR("\a保存点云为空!\n");
system("pause");
}
如果点云对象非空,将点云对象保存为ASCII格式的PCD文件,并输出点云中的点数。如果点云为空,输出错误信息。
总体而言,该程序的目标是将一个文本文件中的点云数据转换为PCL库中的点云对象,并将其保存为PCD文件。这是一个简单的例子,涉及到文件的读取、数据解析和点云对象的创建。
`push_back` 是一个成员函数,用于将元素添加到对象(通常是容器)的末尾。在这里,`push_back` 用于将 `temp_pt`(`pcl::PointXYZRGB` 类型的点)添加到点云对象 `cloud` 的末尾。
具体解释如下:
cloud->push_back(temp_pt);
- `cloud` 是一个指向 `pcl::PointCloud<pcl::PointXYZRGB>` 类型的智能指针。该指针指向一个点云对象,其中包含多个 `pcl::PointXYZRGB` 类型的点。
- `temp_pt` 是一个 `pcl::PointXYZRGB` 类型的点,它包含了点的坐标(x、y、z)和颜色(r、g、b)信息。
- `push_back` 是点云对象 `cloud` 的成员函数,用于将一个点添加到点云的末尾。
所以,这一行代码的作用是将当前通过 `stringstream` 解析得到的点 `temp_pt` 添加到点云对象 `cloud` 中。这个过程会将 `temp_pt` 中的坐标和颜色信息加入到点云对象中,扩充点云的大小。这是构建点云的常用操作,特别是在从文件或其他源读取数据时。