尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

libLAS 1.8.1实战:LAS格式点云读写与命令行工具详解

libLAS 1.8.1实战:LAS格式点云读写与命令行工具详解 简介libLAS 1.8.1 是一个面向 Visual Studio 2017 的 64 位预编译版本专供需要读写 LAS/LAZ 点云数据的 C 开发者使用。该库遵循 ASPRS 标准支持数据读写、元数据处理、过滤和转换其中的 Reader、Writer、Header、Point 等核心类可快速搭建点云解析与生成工具。压缩包约 6MB包含已编译的库文件与头文件可直接集成到 VS2017 工程中省去手动编译的麻烦。64 位版本能利用大内存高效处理大规模点云配合 VS2017 的调试与性能剖析功能无论是格式转换还是区域裁剪、属性统计都能稳定运行。结合点云技术可广泛应用于无人机测绘、BIM、虚拟现实、自动驾驶等场景。对于初学者免去了环境配置的复杂性能够直接实践 LAS 标准格式的读取、解析与生成对于有经验的开发者则提供了稳定、高效的底层库支持。已有 139 人学习下载是 Windows 下进行点云开发与学习的实用选择。 拿到一个.libLAS 1.8.1压缩包时多半是刚接触点云数据处理或者正在评估读写LAS格式该选哪个库。作为老牌开源方案libLAS在LiDAR数据处理圈子里地位不低很多测绘、三维重建、自动驾驶数据预处理的项目里都能看到它的影子。这篇博文不打算讲太多空泛概念直接围绕libLAS 1.8.1这个版本从格式原理、编译细节、代码实战到命令行工具的坑把我实际折腾过的经验整理出来。1. libLAS 1.8.1到底解决了什么问题1.1 LAS格式是点云数据的通用语言激光雷达扫描出来的原始数据本质是一堆离散的三维坐标点附带强度、回波、分类等信息。早期大家直接存ASCII文本一行一行写xyz坐标但问题很明显文件大得离谱解析速度慢而且没法紧凑地保存额外属性。ASPRS组织制定了LAS格式标准用二进制来组织点云数据这才让大规模点云的存储和交换有了统一规范。LAS文件内部结构分三大块头部Header、变长记录VLR、点数据记录Point Records。头部保存文件版本、点的总数、坐标范围、缩放因子等全局信息VLR用于携带坐标参考系CRS、元数据等扩展内容点记录是核心每个点固定字节长按格式号Point Format 0~10不同包含坐标、强度、回波编号、分类、GPS时间等字段。1.2 libLAS在生态中的地位libLAS是专门用于读写LAS格式的C库1.8.1是目前官方发布的最后一个稳定版本。之后项目基本处于维护停滞状态新功能都跑到PDAL那边去了但这不代表libLAS失去价值。很多老项目、在线服务、科研代码还在用它原因很朴素编译简单、C接口稳定、命令行工具齐全读个点云头信息或做格式转换一条命令就够了。选型时我经常拿它跟laspy、PDAL做对比。laspy是纯Python库写脚本很方便但处理亿级点云时性能差距明显PDAL功能强大支持大量滤波算法和点云格式可依赖太重编译适配成本高。libLAS夹在中间恰好满足“快速读写不折腾环境”的现实需求。2. 编译libLAS 1.8.1的环境准备与构建过程2.1 依赖清单与平台注意事项源码编译是绕不开的关卡网上教程虽多但版本匹配问题经常让人卡壳。libLAS 1.8.1依赖三个核心组件CMake构建系统、Boost库智能指针和geometry组件、GDAL用于坐标参考系读写。如果你只做纯坐标读写GDAL不是必需的可以关掉但要做CRS转换或写带投影信息的LAS文件就一定要把GDAL编进来。Windows上要注意64位和32位的区别我用VS2015编译64位版本时踩过几次坑。Boost库版本选1.66及以下比较稳太高版本可能出现Filesystem库接口变化导致的链接错误GDAL版本建议2.x因为GDAL 3.x对C接口做了调整直接编libLAS大概率会报错。如果你要编64位库所有依赖也都得是64位混用32位/64位会在链接阶段出现一堆LNK2038或LNK2019。注意编译前先确认Boost和GDAL是Release版本还是Debug版本两者混用会出现运行时崩溃。没把握的话统一用Release。2.2 CMake配置和关键选项源码解压后创建build目录用CMake GUI或命令行配置都可以。命令行方式更直观推荐直接写cmake .. \ -DCMAKE_BUILD_TYPERelease \ -DWITH_GDALON \ -DWITH_LASZIPON \ -DWITH_TESTSOFF \ -DBOOST_ROOTD:/lib/boost_1_66_0 \ -DGDAL_ROOTD:/lib/gdal-2.4.4几个选项的取舍要讲清楚。WITH_LASZIP默认开启这是对LAS文件做无损压缩的扩展虽然LAS标里不强制但实际工程中加密压缩后的文件很常见建议打开。WITH_TESTS在编译阶段可以先关掉能省不少编译时间等库编完想验证环境再开起来跑一遍单元测试。CMAKE_BUILD_TYPE除了Release也可以用RelWithDebInfo既能保留性能又能调试。配置完成后用cmake --build . --config Release跑编译。以我的经验Boost和GDAL都没问题的情况下整个构建过程大概需要五分钟到二十分钟看机器配置。编译成功后bin目录下会生成lasinfo.exe、las2las.exe、lasmerge.exe、las2txt.exe等命令行工具这些工具在后面的数据处理中几乎天天用到。3. C开发实战读写LAS文件的最核心逻辑3.1 读取LAS文件头信息和点数据在项目里集成libLAS的C接口最常见的任务是遍历点云并提取所需字段。接下来用一段简单的代码展示读取流程#include liblas/liblas.hpp #include fstream int main() { std::ifstream ifs(input.las, std::ios::binary); if (!ifs.is_open()) return -1; liblas::ReaderFactory factory; liblas::Reader reader factory.CreateWithStream(ifs); liblas::Header const header reader.GetHeader(); std::cout 点数: header.GetPointRecordsCount() std::endl; std::cout 格式: static_castint(header.GetDataFormatId()) std::endl; std::cout 坐标范围: header.GetMinX() , header.GetMinY() , header.GetMinZ() ~ header.GetMaxX() , header.GetMaxY() , header.GetMaxZ() std::endl; while (reader.ReadNextPoint()) { liblas::Point const point reader.GetPoint(); double x point.GetX(); double y point.GetY(); double z point.GetZ(); unsigned short intensity point.GetIntensity(); // 处理点数据 } return 0; }读取逻辑并不复杂核心是先创建流再通过ReaderFactory创建Reader随后用GetHeader()拿到全局信息用ReadNextPoint()循环读取每个点。有个细节值得注意点坐标的x、y、z不是直接从文件里读出来的原始整数而是经过缩放因子和偏移量换算后的真实坐标值GetX()内部已经把公式real raw * scale offset算好了所以拿到的值就是实际空间坐标。3.2 写入LAS文件以及缩放因子的设置写入流程是读取的镜像操作。创建一个liblas::Writer设置好Header信息然后逐点写入。但这里有新手最容易出错的地方——缩放因子和坐标偏移。LAS文件的头部需要记录三个轴的缩放因子scale和偏移量offset用于把浮点坐标转换为整数存储。原始点记录里的坐标是int32类型的所以如果缩放因子设得太粗比如0.1坐标精度只能到分米级设得太细比如0.0000000001虽然精度高但坐标值超出int32可表示范围会发生溢出。一个稳妥的实践是在写入之前先遍历一遍数据拿到最小坐标作为偏移量再根据实际精度需求确定scale。比如你的点云坐标在街道尺度上几百米要毫米级精度那scale取0.001就够偏移量设为最小值附近这样原始整数不会太大精度也不损失。std::ofstream ofs(output.las, std::ios::binary); liblas::WriterFactory writerFactory; liblas::Writer writer writerFactory.CreateWithStream(ofs, header); liblas::Point point(header); point.SetCoordinates(x, y, z); point.SetIntensity(intensity); writer.WritePoint(point);头部的SetScale(0.001, 0.001, 0.001)和SetOffset(minX, minY, minZ)务必在创建Writer之前设置好否则自动生成的默认值可能不够用。提醒不要在循环里频繁设置Header、缩放因子这些字段赋值一次就行。头部字段在文件里只写一次循环里设置不会生效反而浪费CPU。4. 命令行工具日常点云处理效率神器4.1 las2las做格式转换和数据裁剪libLAS自带工具集里las2las可能是使用频率最高的。最常见的用途有两个转换点格式、裁剪坐标范围。点格式Point Format的转换单看读取和写入似乎不难但要处理不同格式间字段映射就复杂了。比如把Point Format 1转成0GPS时间字段会丢失从3转到1颜色信息丢失。用las2las一条命令就能搞定las2las -i input.las -o output.las --point-format 1批量裁剪指定范围内的点云也是激光雷达项目里的高频操作。如果想要保留某个区域内的点可以用--keep-tiles参数格式是“最小X 最小Y 最大X 最大Y”las2las -i input.las -o clipped.las --keep-tiles 500000 3000000 501000 3001000注意这里的坐标单位取决于输入文件的CRS单位如果数据是经纬度就是经纬度范围如果是投影坐标就是米。用之前先跑一下lasinfo确认坐标范围避免裁剪出来是空文件。4.2 lasinfo检查数据和lasmerge合并文件拿到一个LAS文件先判断是否正常我的习惯是先跑lasinfo。它输出的信息非常全文件版本、点格式、点数、坐标范围、CRS信息、VLR列表、压缩情况甚至每个点的分类统计。数据有没有问题基本一眼就能看出来。如果要做整个测区的拼接把多个LAS文件合成一个用lasmerge最省事lasmerge -i part1.las part2.las part3.las -o merged.las内部实现会自动重写所有点的坐标并根据合并后的点云范围更新头部信息。批量处理几十个文件时配合shell循环或批处理脚本能极大提升效率。5. 项目实战中常见的坑与排查方法5.1 典型问题速查表现象原因解决方案编译时LNK2019/LNK2038错误Boost或GDAL库版本、架构不匹配统一32/64位和Debug/Release换用Boost 1.66、GDAL 2.x读取LAS时坐标值异常大缩放因子或偏移量设置错误检查Header的Scale和Offset确认单位是米还是经纬度输出文件在CloudCompare里没有坐标系未设置CRS或缺少VLR记录用GDAL集成写入SRS字符串或用las2las的--a_srs指定写入后文件大小暴增点格式选择不当记录字节过长不需要多余字段时用Point Format 0或1文件读取到中途崩溃数据文件损坏或格式不标准先跑lasinfo确认文件完整再用las2las --check修复5.2 最隐蔽的坑坐标偏移量导致的精度丢失这个坑我印象很深。当时处理一个无人机航测生成的点云文件目测坐标范围应该是500000到550000米之间结果读出来的坐标整体少了500公里。后来检查发现是数据文件里的偏移量写错了头部记录的offset是0而原始坐标值在几十万米量级导致real raw * scale offset计算出来的坐标整体偏移了。这类问题光靠肉眼很难发现我总结了一个排查套路读取文件后先看坐标中位数再用las2las抽稀一部分点导出成TXT用QGIS或Python渲染一下如果点位分布位置明显不对基本就是头部元数据和点记录不匹配。另外还有一种情况las2las做坐标参考系统转换时如果原文件带CRS但是libLAS在读取时没能正确识别转换结果就会错得离谱。此时需要手动指定源坐标系用--a_srs EPSG:32650这类参数硬性指定再重新转换。5.3 大文件处理时的性能优化建议处理亿级点云时逐点调用ReadNextPoint()会有点慢因为每个点都有虚函数调用的开销。实际项目里我用过两种优化方式一是改用ReadPointAt(index)随机访问配合多线程分段读取二是先在内存里缓冲一批点再批量写入文件避免频繁IO。第二种方式对写入性能提升非常明显尤其是机械硬盘上差距能有5到10倍。内存不够的场景下可以按分块策略处理先根据坐标范围把整个文件切成若干小块每块单独读取、处理、写输出最后再合并。这样能控制在很小的内存占用下处理超大点云。5.4 libLAS不支持的扩展字段怎么处理LAS格式新增了许多扩展字段比如波形数据包、分类Flags、红外通道等libLAS 1.8.1在解析这些字段时有点力不从心。如果输入文件是LAS 1.4或包含Extra Bytes用libLAS读取时这些额外字段会被直接忽略。这在某些场景下不可接受我一般是先判断文件版本和点格式遇到1.4版本或Extra Bytes较多的文件改用PDAL处理必要时再用libLAS转出基础字段。6. 项目里实际用到的批处理脚本示例结合前面的工具分享一个我常用的批量处理Shell脚本。假设有一个文件夹里的原始点云全部是LAS 1.2需要统一转成Point Format 1并加上EPSG:32650的坐标系信息#!/bin/bash for f in /data/raw/*.las; do basename$(basename $f .las) las2las -i $f \ -o /data/processed/${basename}_fmt1.las \ --point-format 1 \ --a_srs EPSG:32650 done运行前先小批量测试确认格式转换后的点坐标、强度、回波字段都正常再全量跑。碰见半路崩溃的文件把该文件单独拎出来用lasinfo查看多数情况是数据格式不规范导致的。从实际项目角度看libLAS 1.8.1虽然年岁不小仍然是轻量级点云处理场景里极可靠的选择。只要编译环境匹配好、坐标系和缩放因子设置得当日常读写和数据转格式几乎可以无忧使用。我个人的习惯是始终在代码开头跑一次lasinfo做完整性检查写文件前三番五次确认头部元数据这一套流程跑下来libLAS在我的项目里一直很稳当。本文还有配套的精品资源点击获取
返回列表