1. 读取显示.pcd/.ply格式的点云
- 通过
loadPCDFile
/loadPLYFile
或者loadPLYFile
/PLYReader
来载入点云数据 - pcd格式
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
pcl::PointCloud<PointXYZ >::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile<pcl::PointXYZ>("1.pcd", *cloud);
pcl::PCLPointCloud2::Ptr cloud (new pcl::PCLPointCloud2 ());
pcl::PCDReader reader;
reader.read ("1.pcd", *cloud);
#include <iostream>
#include <pcl/io/ply_io.h>
#include <pcl/point_types.h>
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPLYFile <pcl::PointXYZ>("1.pcd", *cloud);
pcl::PCLPointCloud2::Ptr cloud_blob(new pcl::PCLPointCloud2);
pcl::PLYReader reader;
reader.read("1.pcd", *cloud);
- 以下均读取为点类型为
PointXYZ
的点云中,即在调用这些函数前cloud_为pcl::PointCloud<PointXYZ >::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
2. 读取显示.txt格式的点云
- 将txt文件每一行的数据读入到点point中,再将点push_back到点云中
- 注意此处适用于每行中点的数据以空格分割的数据,以逗号分割的稍有不同(有空补充)
cloudPath
为txt文件路径
void readTxtCloud(std::string cloudPath)
{
std::string line;
pcl::PointXYZ point;
std::ifstream txtfile(cloudPath.c_str());
if(!txtfile)
{
std::cout<<"open txt file fail"<<std::endl;
}
while(getline(txtfile, line))
{
std::stringstream ss(line);
ss >> point.x;
ss >> point.y;
ss >> point.z;
cloud->push_back(point);
}
txtfile.close();
}
3. 读取显示.bin格式的点云
- 此处读取过程中直接舍弃了
intensity
强度信息(将其存到a里),保存点x,y,z坐标到点类型为PointXYZ
的点云中
void readBinCloud(std::string cloudPath)
{
pcl::PointXYZ point;
float a=0;
std::ifstream binfile(cloudPath.c_str(),ios::in|ios::binary);
if(!binfile.good())
{
std::cout<<"open bin file fail"<<std::endl;
}
for(int i=0;binfile.good()&&!binfile.eof();i++)
{
binfile.read((char *)&point.x,3*sizeof (float));
binfile.read((char *)&a,sizeof (float));
cloud->push_back(point);
}
binfile.close();
}
4. 读取显示.stl格式的点云
- 首先通过vtkSTLReader读取.stl点云,将其转换为Poly格式再转换为pcl::PointCloud
void readStlCloud(std::string cloudPath)
{
vtkSmartPointer<vtkSTLReader> reader = vtkSmartPointer<vtkSTLReader>::New();
reader->SetFileName(cloudPath.c_str());
reader->Update();
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
polydata = reader->GetOutput();
polydata->GetNumberOfPoints();
pcl::io::vtkPolyDataToPointCloud(polydata,*cloud);
}
5. 读取.pcd/.ply/.txt/.bin/.stl任一格式的点云
- 传入需要读取的点云数据的路径
cloudPath
,判断字符串的后缀名,分别对不同的后缀进行不同的读取方式 - 由于读取.txt/.bin文件时是将点
push_back
到点云中的,所以加上了cloud->clear();
清空点云,否则多次调用函数读取.txt/.bin会导致出现多片点云。 find_last_of
表示从字符串右边开始寻找指定字符,返回该字符在最右处的索引值substr
,str.substr(size_t pos = 0, size_t len = npos)
表示拷贝字符串str从pos开始的len个字符,pos不指定则从0开始拷贝,len不指定的话则默认从pos开始拷贝到字符串末尾
void readPointCloud(std::string cloudPath)
{
cloud_->clear();
if (cloudPath.substr(cloudPath.find_last_of('.')) == ".pcd")
{
try
{
pcl::io::loadPCDFile(cloudPath, *cloud);
}
catch(...)
{
std::cout << "load pcd file error" << std::endl;
}
}
else if (cloudPath.substr(cloudPath.find_last_of('.')) == ".ply")
{
try
{
pcl::io::loadPLYFile(cloudPath,*cloud);
}
catch (...)
{
std::cout<<"load ply file error"<<std::endl;
}
}
else if (cloudPath.substr(cloudPath.find_last_of('.')) == ".txt")
{
try
{
std::string line;
pcl::PointXYZ point;
std::ifstream txtfile(cloudPath.c_str());
if(!txtfile)
{
std::cout<<"open txt file fail"<<std::endl;
}
while(getline(txtfile, line))
{
std::stringstream ss(line);
ss >> point.x;
ss >> point.y;
ss >> point.z;
cloud->push_back(point);
std::cout<<point<<std::endl;
}
txtfile.close();
}
catch(...)
{
std::cout<<"load ply file error"<<std::endl;
}
}
else if (cloudPath.substr(cloudPath.find_last_of('.')) == ".bin")
{
try
{
pcl::PointXYZ point;
float a=0;
std::ifstream binfile(cloudPath.c_str(),ios::in|ios::binary);
if(!binfile.good())
{
std::cout<<"open bin file fail"<<std::endl;
}
for(int i=0;binfile.good()&&!binfile.eof();i++)
{
binfile.read((char *)&point.x,3*sizeof (float));
binfile.read((char *)&a,sizeof (float));
cloud->push_back(point);
}
binfile.close();
}
catch(...)
{
std::cout<<"load bin file error"<<std::endl;
}
}
else if (cloudPath.substr(cloudPath.find_last_of('.')) == ".stl")
{
try
{
vtkSmartPointer<vtkSTLReader> reader = vtkSmartPointer<vtkSTLReader>::New();
reader->SetFileName(cloudPath.c_str());
reader->Update();
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
polydata = reader->GetOutput();
polydata->GetNumberOfPoints();
pcl::io::vtkPolyDataToPointCloud(polydata,*cloud);
}
catch(...)
{
std::cout<<"load stl file error"<<std::endl;
}
}
pcl::io::savePCDFile<pcl::PointXYZ>("wind.pcd", *cloud);
}
6. 显示上述格式的点云数据
- 调用显示函数
showPointCloud
前,先调用readPointCloud
函数读入点云
void showPointCloud(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
{
viewer_->setBackgroundColor(0,0,0);
viewer_->removeAllShapes();
viewer_->removeAllPointClouds();
viewer_->removeAllCoordinateSystems();
pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> fildColor(cloud,"z");
viewer_->addPointCloud<pcl::PointXYZ>(cloud,fildColor);
viewer_->resetCamera();
}