1.pcd文件格式
FIELDS x y z
代表后面每行有三个数字x,y,z,有时后面会跟上一些其他数字,如强度,rgb数值,法线向量等。
WIDTH 35947
HEIGHT 1
代表无序点云
DATA ascii
代表以ascill编码,即用记事本可以打开,还有binary编码,记事本打开会乱码。open3d保存文件默认以ascill格式保存。
2.读入,显示,保存
open3d见下面
pcl:
#include <iostream>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>//可视化
typedef pcl::PointXYZ PointT;
int main() {
pcl::PointCloud<PointT>::Ptr cloud(new pcl::PointCloud<PointT>); //点云指针文件,指向结构体的指针
pcl::io::loadPCDFile("E:/vs/pcldata/bunny1.pcd", *cloud); //读取点云
pcl::PointCloud<PointT> outcloud = *cloud; //点云文件,从指针所指读取,结构体文件
int pnumber = (int)cloud->size(); //等价于outcloud.size
std::cout << pnumber << endl;
pcl::visualization::PCLVisualizer viewer("registration Viewer"); //窗口名
viewer.setBackgroundColor(255, 255, 255); //设置白背景
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_paint(cloud, 0, 255, 0);
viewer.addPointCloud(cloud, cloud_paint, "source cloud");
while (!viewer.wasStopped()) //使显示窗口停留
{
viewer.spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
pcl::io::savePCDFile("E:/vs/pcldata/result.pcd", outcloud); //保存数据
return 0;
}
3.不同点云格式的转换
一般用的比较多的是pcd,直接使用cloudcompare转,一步到位
pcl:
//las转pcd,需要liblas库,且仅支持liblas声明的las文件
#include <iostream>
#include <cstdlib>
#include <liblas/liblas.hpp>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
using namespace std;
int main (int argc, char** argv)
{
//std::ifstream ifs(argv[1], std::ios::in | std::ios::binary); // 打开las文件
std::ifstream ifs;
ifs.open("E:/vs/pcldata/ground.las", std::ios::in | std::ios::binary);
if (!ifs.is_open())
return false;
liblas::ReaderFactory f;
liblas::Reader reader = f.CreateWithStream(ifs); // 读取las文件
unsigned long int nbPoints=reader.GetHeader().GetPointRecordsCount();//获取las数据点的个数
pcl::PointCloud<pcl::PointXYZRGB> cloud;
cloud.width = nbPoints; //保证与las数据点的个数一致
cloud.height = 1;
cloud.is_dense = false;
cloud.points.resize (cloud.width * cloud.height);
int i=0;
uint16_t r1, g1, b1;
int r2, g2, b2;
uint32_t rgb;
while(reader.ReadNextPoint())
{
// 获取las数据的x,y,z信息
cloud.points[i].x = (reader.GetPoint().GetX());
cloud.points[i].y = (reader.GetPoint().GetY());
cloud.points[i].z = (reader.GetPoint().GetZ());
//获取las数据的r,g,b信息
r1 = (reader.GetPoint().GetColor().GetRed());
g1 = (reader.GetPoint().GetColor().GetGreen());
b1 = (reader.GetPoint().GetColor().GetBlue());
r2 = ceil(((float)r1/65536)*(float)256);
g2 = ceil(((float)g1/65536)*(float)256);
b2 = ceil(((float)b1/65536)*(float)256);
rgb = ((int)r2) << 16 | ((int)g2) << 8 | ((int)b2);
cloud.points[i].rgb = *reinterpret_cast<float*>(&rgb);
i++;
}
pcl::io::savePCDFileASCII ("E:/vs/pcldata/ground.pcd", cloud);//存储为pcd类型文件
return (0);
}
open3d:
# 读取任意路径的点云并显示,保存,可以实现ply与pcd之间的转化
import open3d as o3d
import numpy as np
import win32ui,os,sys,time
def getfilepath(path=f'{os.getcwd()}'):
# print(os.getcwd())
dlg =win32ui.CreateFileDialog(1)
dlg.SetOFNInitialDir(path)
dlg.DoModal()
filename=dlg.GetPathName();#
return filename
print("读取点云并可视化")
pcd = o3d.io.read_point_cloud(f"{getfilepath()}")
print(pcd);print(np.asarray(pcd.points))
o3d.visualization.draw_geometries([pcd])
o3d.io.write_point_cloud("./pointcloud_data/bunny2.pcd",pcd,True)
#可换成绝对路径,pcd与ply文件后缀更改即可
4.裁剪
#只能以正方形进行裁剪,也可以使用cloudcompare软件进行裁剪
import open3d as o3d
import numpy as np
pcd = o3d.io.read_point_cloud("./pointcloud_data/bun_zipper.ply")
vis = o3d.visualization.VisualizerWithEditing()
#<class 'open3d.cpu.pybind.visualization.VisualizerWithEditing'>
print(type(vis))
vis.create_window()
vis.add_geometry(pcd)
vis.run()
# vis.run()
vis.destroy_window()
pcd = o3d.io.read_point_cloud("./pointcloud_data/edit.ply")
o3d.io.write_point_cloud("./pointcloud_data/bunny1.pcd",pcd,True)
# k锁定,长按鼠标左键进行裁剪,c保留裁剪后的区域,s保存文件
5.如何配置第三方库
a.添加环境变量,首先在计算机内配置环境变量,然后在这配置,添加bin文件
b.更改lib和include文件目录
c.添加lib文件