1. 相关头文件
点云文件是众多点组成的一个集合,点作为组成点云的最小元素,包含了空间位置XYZ和颜色信息RGB。当然,对颜色的描述可以是灰度值(Intensity)、HSV(HSV颜色空间描述)和Alpha(透明度等)。因此常见的点的类型有: PointXYZ、PointXYZRGB、PointXYZI和PointXYZHSV、POINTXYZRGBA等。从代码上来看,需要导入文件读入的IO模块,点的类型模块。
/*
* 本例以读取OBJ文件为例
*/
#include<iostream>
using namespace std;
#include<pcl/point_types.h> // 点的类型
// 三种不同的文件io
#include<pcl/io/pcd_io.h> // 本例中多余
#inlcude<pcl/io/obj_io.h>
#include<pcl/io/ply_io.h> // 本例中多余
#include<pcl/visualization/pcl_visualizer.h> // 显示模块
//- 定义点的类型: 使用Typedef进行定义,简化代码
typedef pcl::PointXYZRGB PointT;
typedef pcl::PointCloud<PointT> PointCloud;
同时,在CMakeLists中需要添加对PCL库的依赖:
# 与PCL无关的内容
cmake_minimum_required(Version 2.8)
project(pcl_io_display)
add_executable(io_display main.cpp)
# PCL相关
find_package(PCL 1.8 REQUIRED) # 指定了PCL版本
if(PCL_FOUND)
#根据安装方法可能不同
## /usr/include下面是pcl-1.8: ${PCL_INCLUDE_DIRS}/pcl-1.8/pcl/
## /usr/include下面是pcl: ${PCL_INCLUDE_DIRS}即可
include_directories(${PCL_INCLUDE_DIRS}/pcl-1.8/pcl/)
add_definitions(${PCL_DEFINITIONS})
link_directories(${PCL_LIBRARY_DIRS})
target_link_libraries(io_display ${PCL_LIBRARIES})
endif()
2. 读取点云数据
点云文件通常以ply、pcd和obj结尾,通常ply文件仅包含点的XYZ信息,OBJ文件包含了XYZRGB信息。PCD文件是pcl原生支持文件类型,其点的信息定义可以是多样的(XYZI, XYZRGB, XYZA等), 其具体定义是通过文件头FIELDS后的信息来确定的。点云的读取方法:
//- 输入为文件路径和点云的引用
void LoadOBJ(string fName, PointCloud& cloud){
int ret = pcl::io::loadOBJFile(fName, cloud); //- 二次引用,读入点云存入cloud中
if(ret<0){
cout << "点云没有成功读入" << endl; //- 返回小于0,读入失败
} else {
cout << "点云成功读入" << endl; //- 返回大于等于0,读入成功
}
}
3. 点云的显示
在完成点云之后,可以使用pcl显示点云,实现点云的可视化。
//- 显示点云
pcl::visualization::PCLVisualizer::Ptr visualizer(
new pcl::visualization::PCLVisualizer("点云显示窗口"));
// 背景RGB(此处为黑色), viewport缺省
visualizer->setBackgroundColor(255,255,255);
// 添加显示的点云及对应标签,可以添加多个点云,通过标签对应,后续通过标签可以进行单独的设置
visualizer->addPointCloud<PointT>(cloud, "PointCloud");
// 设置显示单个点的属性: 如每个点显示的像素大小,可以多次设置多个属性
// PointCloud是刚刚添加的标签
visualizer->setPointCloudRenderingProperties(
pcl::visualization::PCL_VISUALIZER_FONT_SIZE, 5, "PointCloud"
);
//- 坐标系设置
visualizer->addCoordinateSystem(0.5);
//- 循环显示,每次显示之间可以添加函数处理点云
while(!visualizer->wasStopped()){
visualizer->spinOnce(100);
sleep(0.01); //休眠100ms
}
4. 代码整理
整理之后的可运行代码如下, 存在问题。正常的OBJ文件,应该附带一个MLT文件来记录各种材质信息,包括彩色信息。PCL提供两个函数pcl::io::loadPolygonFileOBJ() 和 pcl::io::loadOBJFile() 从这种OBJ文件中读取信息到数据类型pcl::TextureMesh,然后在viewer中使用addTextureMesh进行可视化。
本例中使用XYZRGB尽管可以显示处三维点云,但是点云失去了原来的色彩信息,即全为黑色。
#include <iostream>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h> // 本例中多余
#include <pcl/io/ply_io.h> // 本例中多余
#include <pcl/io/obj_io.h>
#include <thread>
using namespace std;
typedef pcl::PointXYZRGBA PointT;
typedef pcl::PointCloud<PointT> PointCloud;
//- 输入为文件路径和点云的引用
void LoadOBJ(string fName, PointCloud& cloud){
int ret = pcl::io::loadOBJFile(fName, cloud); //- 二次引用,读入点云存入cloud中
if(ret<0){
cout << "点云没有成功读入" << endl; //- 返回小于0,读入失败
} else {
cout << "点云成功读入" << endl; //- 返回大于等于0,读入成功
}
}
int main() {
string fName = "/home/kylin/CLionProjects/教育小车视觉SLAM/obj/t1.obj";
PointCloud::Ptr cloud(new PointCloud);
LoadOBJ(fName, *cloud);
cout << "总点数: " << cloud->points.size() << endl;
//- 显示点云
pcl::visualization::PCLVisualizer::Ptr visualizer(
new pcl::visualization::PCLVisualizer("点云显示窗口"));
// 背景RGB(此处为黑色), viewport缺省
visualizer->setBackgroundColor(255,255,255);
// 添加显示的点云及对应标签,可以添加多个点云,通过标签对应,后续通过标签可以进行单独的设置
visualizer->addPointCloud<PointT>(cloud, "PointCloud");
// 设置显示单个点的属性: 如每个点显示的像素大小,可以多次设置多个属性
// PointCloud是刚刚添加的标签
visualizer->setPointCloudRenderingProperties(
pcl::visualization::PCL_VISUALIZER_FONT_SIZE, 5, "PointCloud"
);
//- 坐标系设置
visualizer->addCoordinateSystem(0.5);
//- 循环显示,每次显示之间可以添加函数处理点云
while(!visualizer->wasStopped()){
visualizer->spinOnce(100);
sleep(0.01); //休眠100ms
}
return 0;
}