基于Win系统下PCL库入门到实践:LASreader库和LASwriter(附代码链接)
和是处理的核心库。之前已经描述过,LAS(.las / .laz)是 美国 ASPRS(摄影测量与遥感协会)制定的点云标准格式,广泛用于航空激光雷达(ALS)、地面激光雷达(TLS)、移动测量(MLS)。如果要做点云科研、地图测绘、无人驾驶、三维建模,几乎必然会接触 LAS 数据。是高效读取的方式,读取时还能访问每个点的:XYZ、强度、分类、时间戳、扫描线 ID、波形信息等。把处理后的点云数据写回
LASreader 和 LASwriter 是处理 LiDAR 点云数据(LAS/LAZ 格式) 的核心库。
之前已经描述过,LAS(.las / .laz)是 美国 ASPRS(摄影测量与遥感协会)制定的点云标准格式,广泛用于航空激光雷达(ALS)、地面激光雷达(TLS)、移动测量(MLS)。如果要做点云科研、地图测绘、无人驾驶、三维建模,几乎必然会接触 LAS 数据。
LASreader 是高效读取的方式,读取时还能访问每个点的 属性:XYZ、强度、分类、时间戳、扫描线 ID、波形信息等。
LASwriter 把处理后的点云数据写回标准 LAS/LAZ 文件,保证格式兼容性。可以指定 LAS header 信息,比如:点数、范围、坐标系、版本、scale、offset。能写成压缩格式(.laz),节省存储和传输成本。
PCL 主要面向点云处理算法,而 LASlib 更偏向 点云数据存储和 I/O。如果要做 LiDAR 工程,就必须学会 PCL + LASlib 的结合:PCL 处理 → LASwriter 存储。
1.LASreader库
1.1.读取文件
先介绍库中常用的一些。
LASreaderOpener opener;
LASread *LAS_file;
opener.set_file_name("las文件路径");
LAS_file = opener.open();
上述的代码就是打开一个las/laz文件流程,先定义中间变量opener,用其获取路径,最后用open的方法打开并给了定义的读取变量。
1.2.获取header信息
首先要了解header中的点信息,常用的有这些:以上述定义的LAS_file为例读取其header信息。
LAS_file->header.number_of_points_records
LAS_file->header.point_count //点的数量
LAS_file->header.x_scale_factor
LAS_file->header.y_scale_factor
LAS_file->header.z_scale_factor//x,y,z缩放比例
LAS_file->header.x_offset
LAS_file->header.y_offset
LAS_file->header.z_offset//x,y,z偏移量
LAS_file->header.max_x
LAS_file->header.max_y
LAS_file->header.max_z
LAS_file->header.min_x
LAS_file->header.min_y
LAS_file->header.min_z//x,y,z最大最小点
LAS_file->header.point_data_format//点云格式
LAS_file->header.point_data_record_length//对应格式占用字节
1.3.获取point信息
其次要了解point中的点信息:
LAS_file->point.get_X()
LAS_file->point.get_Y()
LAS_file->point.get_Z()//获得原始xyz数据
LAS_file->point.get_x()
LAS_file->point.get_y()
LAS_file->point.get_z()//获得真实xyz数据
LAS_file->point.get_R()
LAS_file->point.get_G()
LAS_file->point.get_B()//若点具备RGB,获得其对应的RGB值
在 LAS/LAZ 格式里,点的 X/Y/Z 并不是直接存储的浮点坐标,而是存储的 整数值,需要通过 header 里的 scale 和 offset 转换成实际坐标。LAS 标准里的公式是:

如果用 get_X()/get_Y()/get_Z(),返回的是原始的整数(int32)直接拿来显示,点可能全都飘到坐标系外面去了
如果用 get_x()/get_y()/get_z()(小写),LASlib 会自动按照 header 里的 scale_factor 和 offset做转换,得到真实的浮点坐标,PCL 里显示才正常。
当然reader库中还包含了一些常见的功能函数:
get_format()//获取点云格式;
get_index()//搜索指定点信息;
get_transform()//变换点云格式
read_point()//读到最后一个点,返回false
get_min_x() get_max_x()
get_min_y() get_max_y()
get_min_z() get_max_z() //获得las文件中的最大最小xyz
了解这些之后就可以进行las文件读取的代码实操了。
2.LASreader库实现
2.1.创建项目
这里先准备好las/laz文件,在下载LASlib这个路径下会提供例子。

打开QT,新建一个C++项目,

这里是具体项目路径以及项目名称。



再将生成的main.cpp运行,正常执行就没问题了。

2.2.导入路径
然后需要将之前链接路径的pri文件导入进来,按下ctrl+s保存后,划线文件就显示在左边了。
include(D:/PCL/PCL/pcl_path.pri)

2.3.详细代码讲解
首先添加头文件
#include <thread>
#include <pcl/point_cloud.h>
#include <pcl/visualization/cloud_viewer.h>
#include <lasreader.hpp>
#include <iostream>
第一步,先创建空白点云集以及点用于读取las文件中的点。
pcl::PointCloud<pcl::PointXYZRGB>::Ptr Cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
pcl::PointXYZRGB point;
第二步,创建读取las文件的变量,并读取,这在前面就已经描述过:
LASreadOpener opener;
opener.set_file_name("D:\\PCL\\LAStools-master\\data\\house.laz");
LASreader *las_file = opener.open();
这里加入一个打印调试:
if (!las_file) {
std::cerr << "❌ Failed to open LAS file!" << std::endl;
return -1;
}
设定点云的宽高:宽就是点的总数,而这里是无序点云,所以height直接是1。
Cloud->width = las_file->header.number_of_point_records;
Cloud->height = 1;
接下来就是读取点:当然这里需要一个能在读到最后点返回false的
while (las_file->read_point())
{
point.x = las_file->point.get_x();
point.y = las_file->point.get_y();
point.z = las_file->point.get_z();
point.r = las_file->point.get_R()>>8;
point.g = las_file->point.get_G()>>8;
point.b = las_file->point.get_B()>>8;
Cloud->push_back(point);
}
上述代码中point是我们自己定义的点,用于储存打开的las文件的点,由于las文件中的RGB值是属于(0-255),而这里的值范围是(0-1),所以要右移八位或者%255。
push_back把构造好的 point(单个点,类型是 pcl::PointXYZRGB)追加到点云容器 Cloud 的末尾。
读取完所有点后,关闭las文件,并删除这个中间变量,释放内存;
las_file->close();
delete las_file;
原本这里我就直接创建可视化去显示的,但是,文件夹给的这个示例laz点云可能是真时坐标的值超越了显示的这个范围,出现看不到点的现象,这里我的解决方案时,利用最大最小点拉回到中心。下述代码中,利用其方法直接读取对应XYZ的最大最小值,直接回去其XYZ中心点,再遍历多有的点,并减去这个值,让其拉回显示范围。
double x_min,y_min,z_min,x_max,y_max,z_max;
x_min = las_file->get_min_x();
y_min = las_file->get_min_y();
z_min = las_file->get_min_z();
x_max = las_file->get_max_x();
y_max = las_file->get_max_y();
z_max = las_file->get_max_z();
double x_center = (x_min + x_max)/2.0;
double y_center = (y_min + y_max)/2.0;
double z_center = (z_min + z_max)/2.0;
for (auto &p : Cloud->points) {
p.x -= x_center;
p.y -= y_center;
p.z -= z_center;
}
最后一步就是创建可视化:
// 创建 CloudViewer
pcl::visualization::CloudViewer viewer("LAS Cloud Viewer");
viewer.showCloud(Cloud, "cloud");
viewer.runOnVisualizationThread([&](pcl::visualization::PCLVisualizer &vis){
vis.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "cloud");
vis.setBackgroundColor(1,1,1);
});
// 保持显示
while (!viewer.wasStopped()) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
setPointCloudRenderingProperties设置点的尺寸。
setBackgroundColor设置显示背景的颜色,1,1,1就是分别对应rgb的值,全白。
最后,运行,查看结果:

这里希望自己将代码重新整理并重组,如有需要完整代码可以关注私信回。
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)