PDAL点云处理怎么做?管道流如何配置?

GIS基础理论
Dr.GIS
wowwwai GIS研习社 · 工具流程与项目排障

做激光雷达数据预处理时,很多 GIS 同学会遇到一个问题:PDAL点云处理怎么做?管道流如何配置? 如果你手里有 LAS、LAZ、E57 或 PLY 点云文件,想完成裁剪、重投影、滤波、分类、格式转换等操作,PDAL 的管道流是一种非常适合批处理和自动化的方式。

本文以 GIS 实际工作流为主线,讲清楚 PDAL 点云处理的基本思路、PDAL 管道流配置方法、常见过滤器写法,以及如何检查处理结果是否正确。适合 QGIS、Python GIS、三维数据处理和测绘点云入门用户阅读。

PDAL点云处理与PDAL管道流配置流程图
PDAL 管道流的基本逻辑:读取点云、串联过滤器、输出处理结果。

引言:为什么用 PDAL 做点云处理

PDAL 是 Point Data Abstraction Library 的缩写,可以理解为“点云数据抽象与处理库”。它和 GDAL 在栅格、矢量数据中的作用类似,专门面向点云数据读写、转换和处理。

在 GIS 场景中,PDAL 点云处理常见于以下任务:

  • LAS 与 LAZ 点云格式转换。
  • 按范围裁剪点云数据。
  • 点云坐标系重投影。
  • 按分类值、强度、高程过滤点。
  • 生成地面点、非地面点或指定类别点云。
  • 与 Python、QGIS、PostGIS 或三维可视化流程衔接。

PDAL 的核心优势是可以把多个处理步骤写成一个 JSON 管道文件。这样既方便复现,也适合批量处理大量点云文件。

背景:PDAL 点云处理适合解决什么问题

很多初学者会直接用图形软件打开 LAS 文件,然后手动裁剪、导出、再处理。这样做适合少量数据,但在项目中经常会遇到几个问题:

  • 点云文件体积很大,手工操作容易卡顿。
  • 同一套处理参数需要重复应用到多个分幅数据。
  • 坐标系、范围、分类字段不统一,结果难以检查。
  • 处理步骤无法完整记录,后期难以复现。

PDAL 管道流配置正是为了解决这些问题。它把“读入数据、处理数据、写出数据”拆成多个阶段,每个阶段负责一个明确任务。你只需要保存 JSON 配置文件,就可以重复执行同样的处理流程。

例如,一个典型的 PDAL pipeline 可以完成:

  1. 读取 input.laz。
  2. 裁剪到指定矩形范围。
  3. 把坐标系从 EPSG:4547 转为 EPSG:4326。
  4. 只保留地面点分类。
  5. 输出为 output.laz。

原理:PDAL 管道流配置的核心结构

PDAL 管道流的配置文件通常是 JSON 格式,核心字段是 pipeline。一个管道由多个 stage 组成,每个 stage 可以是 reader、filter 或 writer。

阶段类型 作用 常见示例
reader 读取点云数据 readers.lasreaders.e57readers.ply
filter 处理中间点云 filters.cropfilters.rangefilters.reprojection
writer 输出处理结果 writers.laswriters.gdalwriters.text

最简单的 PDAL 点云处理管道如下,它只是把一个 LAZ 文件转换为 LAS 文件:

{
  "pipeline": [
    "input.laz",
    "output.las"
  ]
}

这是一种简写方式。实际项目中更推荐写完整 stage,方便明确文件类型、坐标系、压缩选项和过滤参数。

{
  "pipeline": [
    {
      "type": "readers.las",
      "filename": "input.laz"
    },
    {
      "type": "writers.las",
      "filename": "output.laz",
      "compression": "laszip"
    }
  ]
}

理解 PDAL 管道流配置时,要记住一个原则:上一个阶段的输出,会作为下一个阶段的输入。因此,裁剪、重投影、过滤的顺序会影响最终结果。

步骤:从零配置一个 PDAL 点云处理管道

步骤 1:确认 PDAL 是否安装成功

在命令行中执行:

pdal --version

如果能看到 PDAL 版本号,说明命令行环境可用。如果提示找不到命令,需要检查安装路径和环境变量。

如果你使用 Conda 环境,可以通过以下方式安装:

conda install -c conda-forge pdal

安装完成后,建议再执行:

pdal --drivers

这个命令可以查看当前 PDAL 支持的 readers、filters 和 writers。不同安装方式支持的驱动可能略有差异,遇到某个 reader 不可用时,应先检查驱动列表。

步骤 2:查看点云文件基本信息

在正式处理前,先用 pdal info 查看点云元数据:

pdal info input.laz

重点关注以下信息:

  • 点云范围:最小 X、最大 X、最小 Y、最大 Y、最小 Z、最大 Z。
  • 坐标系信息:是否包含 SRS 或 EPSG 代码。
  • 点数量:用于判断处理后点数是否异常。
  • 维度字段:是否包含 Classification、Intensity、ReturnNumber 等字段。

如果数据没有坐标系信息,PDAL 无法自动判断其空间参考。这时需要在 reader 或重投影阶段显式指定。

步骤 3:配置 LAS/LAZ 读取与输出

先创建一个名为 pipeline.json 的文件,写入基础管道:

{
  "pipeline": [
    {
      "type": "readers.las",
      "filename": "input.laz"
    },
    {
      "type": "writers.las",
      "filename": "output.laz",
      "compression": "laszip"
    }
  ]
}

执行管道:

pdal pipeline pipeline.json

如果能生成 output.laz,说明基础 PDAL pipeline 已经跑通。后续所有处理都可以在 reader 和 writer 中间增加 filters。

步骤 4:用 filters.crop 裁剪点云范围

点云裁剪是 PDAL 点云处理最常见的任务之一。下面示例使用二维矩形范围裁剪:

{
  "pipeline": [
    {
      "type": "readers.las",
      "filename": "input.laz"
    },
    {
      "type": "filters.crop",
      "bounds": "([500000,501000],[3400000,3401000])"
    },
    {
      "type": "writers.las",
      "filename": "clip.laz",
      "compression": "laszip"
    }
  ]
}

bounds 的格式是:

([minX,maxX],[minY,maxY])

如果还要限制高程范围,可以写成:

([minX,maxX],[minY,maxY],[minZ,maxZ])

裁剪前一定要确认坐标单位。如果数据是投影坐标,X、Y 通常是米;如果数据是经纬度坐标,X、Y 是度。把米制范围误用于经纬度数据,是 PDAL 管道流配置中非常常见的错误。

步骤 5:用 filters.reprojection 重投影点云

如果需要把点云从一个坐标系转换到另一个坐标系,可以使用 filters.reprojection

{
  "pipeline": [
    {
      "type": "readers.las",
      "filename": "input.laz",
      "spatialreference": "EPSG:4547"
    },
    {
      "type": "filters.reprojection",
      "in_srs": "EPSG:4547",
      "out_srs": "EPSG:4326"
    },
    {
      "type": "writers.las",
      "filename": "reproject_4326.laz",
      "compression": "laszip"
    }
  ]
}

这里有两个关键点:

  • in_srs 是输入点云实际坐标系。
  • out_srs 是输出点云目标坐标系。

如果 input.laz 已经包含正确坐标系,通常可以不写 reader 的 spatialreference。但如果源数据缺少坐标系,必须显式指定,否则重投影结果可能错误。

步骤 6:用 filters.range 按分类或高程过滤

LAS 点云通常包含 Classification 字段。常见分类中,2 通常表示地面点,但实际项目仍应以数据生产说明为准。

只保留地面点的示例:

{
  "pipeline": [
    {
      "type": "readers.las",
      "filename": "input.laz"
    },
    {
      "type": "filters.range",
      "limits": "Classification[2:2]"
    },
    {
      "type": "writers.las",
      "filename": "ground_only.laz",
      "compression": "laszip"
    }
  ]
}

按高程过滤的示例:

{
  "pipeline": [
    {
      "type": "readers.las",
      "filename": "input.laz"
    },
    {
      "type": "filters.range",
      "limits": "Z[0:200]"
    },
    {
      "type": "writers.las",
      "filename": "z_0_200.laz",
      "compression": "laszip"
    }
  ]
}

多个条件可以组合使用:

{
  "pipeline": [
    {
      "type": "readers.las",
      "filename": "input.laz"
    },
    {
      "type": "filters.range",
      "limits": "Classification[2:2],Z[0:200]"
    },
    {
      "type": "writers.las",
      "filename": "ground_z_0_200.laz",
      "compression": "laszip"
    }
  ]
}

步骤 7:组合裁剪、重投影和分类过滤

下面是一个较完整的 PDAL 管道流配置示例:先读取 LAZ,裁剪研究区,过滤地面点,再输出压缩 LAZ。

{
  "pipeline": [
    {
      "type": "readers.las",
      "filename": "input.laz",
      "spatialreference": "EPSG:4547"
    },
    {
      "type": "filters.crop",
      "bounds": "([500000,501000],[3400000,3401000])"
    },
    {
      "type": "filters.range",
      "limits": "Classification[2:2]"
    },
    {
      "type": "writers.las",
      "filename": "clip_ground.laz",
      "compression": "laszip"
    }
  ]
}

如果目标是输出经纬度坐标,可以加入重投影:

{
  "pipeline": [
    {
      "type": "readers.las",
      "filename": "input.laz",
      "spatialreference": "EPSG:4547"
    },
    {
      "type": "filters.crop",
      "bounds": "([500000,501000],[3400000,3401000])"
    },
    {
      "type": "filters.range",
      "limits": "Classification[2:2]"
    },
    {
      "type": "filters.reprojection",
      "in_srs": "EPSG:4547",
      "out_srs": "EPSG:4326"
    },
    {
      "type": "writers.las",
      "filename": "clip_ground_4326.laz",
      "compression": "laszip"
    }
  ]
}

这里的顺序很重要。通常建议先在投影坐标系下裁剪,再重投影到经纬度。原因是投影坐标下范围单位是米,更适合工程范围控制。

步骤 8:检查输出结果是否正确

处理完成后,不要只看文件是否生成,还要检查结果是否符合预期。

可以先查看输出文件信息:

pdal info clip_ground.laz

重点检查:

  • 点数量是否明显小于原始文件。
  • 边界范围是否落在裁剪范围内。
  • 坐标系是否是预期 EPSG。
  • Classification 是否只剩目标类别。
  • Z 值范围是否符合过滤条件。

如果你习惯图形界面,也可以把结果加载到 QGIS 中查看。QGIS 可以用于快速检查点云位置、范围和坐标系是否合理。

常见坑:PDAL 管道流配置容易出错的地方

1. 坐标系缺失导致重投影错误

很多 LAS/LAZ 文件并不一定写入完整坐标系信息。此时直接执行 filters.reprojection,可能无法得到正确结果。

处理方法是先用 pdal info 检查空间参考。如果缺失,就在 reader 中增加 spatialreference,并确认 in_srs 与真实数据一致。

2. 裁剪范围单位写错

如果输入是 EPSG:4326,经纬度单位是度;如果输入是高斯投影、UTM 或 CGCS2000 投影坐标,单位通常是米。

常见错误是把 Web 地图上的经纬度范围直接用于米制点云,或者把米制坐标范围用于经纬度点云。结果可能是输出空文件,或者裁剪位置完全不对。

3. filters 顺序不合理

PDAL pipeline 是按顺序执行的。不同顺序会得到不同结果。

  • 先裁剪再重投影:适合按源数据工程坐标范围裁剪。
  • 先重投影再裁剪:适合按目标坐标系范围裁剪。
  • 先过滤分类再裁剪:可以减少后续处理点数,但不适合需要完整范围统计的场景。

如果不确定顺序,建议先画出“输入、过滤、输出”的流程图,再写 JSON。

4. Classification 值理解错误

LAS 标准中有常见分类编码,但实际数据可能被生产单位重新定义。不要默认所有数据的 Classification=2 都一定是可靠地面点。

建议同时查看数据说明、元数据和可视化结果,确认分类含义。

5. 输出 LAZ 压缩选项漏写

如果希望输出压缩 LAZ,通常需要在 writers.las 中设置:

"compression": "laszip"

否则输出可能是未压缩 LAS,文件体积会明显变大。具体是否支持 LAZ 压缩,也与当前 PDAL 安装环境有关。

方法比较:PDAL、QGIS 和 Python 点云处理怎么选

方法 适合场景 优点 局限
PDAL 命令行管道 批量点云处理、格式转换、自动化流程 可复现、适合脚本化、处理步骤清晰 需要理解 JSON 配置和命令行
QGIS 点云工具 快速查看、简单处理、结果检查 图形界面直观,适合 GIS 初学者 批量自动化能力不如管道流
Python 调用 PDAL 与数据分析、批处理系统集成 可与 GeoPandas、Rasterio、数据库流程结合 环境配置更复杂,需要 Python 基础
专业点云软件 人工分类、精细编辑、三维测图 交互编辑能力强 自动化和开源流程复现成本较高

如果你只是偶尔查看点云,QGIS 更直观。如果你需要稳定处理很多分幅,PDAL 点云处理更适合。如果你还要把处理结果接入数据生产系统,Python 调用 PDAL 会更灵活。

检查清单:写 PDAL pipeline 前先确认这些项

  • 输入文件格式是否为 PDAL 当前环境支持的格式。
  • 输入点云是否包含正确坐标系。
  • 裁剪范围使用的是源坐标系还是目标坐标系。
  • 范围单位是米还是度。
  • 是否需要保留全部点维度字段。
  • 是否需要按 Classification、Z、Intensity 等字段过滤。
  • 输出格式是 LAS、LAZ、PLY、CSV 还是栅格。
  • 输出 LAZ 是否需要设置 compression
  • 处理后是否用 pdal info 检查点数、范围和坐标系。
  • 是否把 pipeline.json 与项目数据处理记录一起归档。

FAQ:PDAL 点云处理常见问题

PDAL 管道流配置一定要写 JSON 吗?

不一定。简单格式转换可以直接在命令行中完成,例如 pdal translate input.laz output.las。但只要涉及多个处理步骤,推荐使用 JSON pipeline,因为配置更清晰,也便于复现。

PDAL 可以直接处理 LAZ 文件吗?

通常可以,但取决于你的 PDAL 安装环境是否支持 LAZ 压缩相关能力。建议执行 pdal --drivers 查看 readers.laswriters.las 是否可用,并在输出 LAZ 时检查压缩选项。

为什么 PDAL 裁剪后输出是空文件?

最常见原因是裁剪范围与点云坐标系不一致。比如输入点云是米制投影坐标,但你填写了经纬度范围。也可能是 X、Y 顺序写反,或者范围本身不覆盖点云数据。

PDAL 重投影后点云位置不对怎么办?

先检查源数据真实坐标系。如果原始 LAS/LAZ 没有空间参考,必须在 reader 或 filters.reprojection 中明确指定 in_srs。如果 in_srs 写错,输出位置一定会错。

PDAL pipeline 中 filters 的顺序会影响结果吗?

会。PDAL 管道流按数组顺序逐步执行。裁剪、过滤、重投影的顺序不同,结果可能不同。建议根据业务逻辑决定顺序,并在每个关键步骤后用小样本验证。

PDAL 能把点云转成栅格 DEM 吗?

可以使用 writers.gdal 等方式把点云插值或栅格化为 DEM 类结果。但 DEM 生成涉及分辨率、插值方法、地面点选择和空洞处理,不建议和基础格式转换混在一个未经验证的流程中。

结论:PDAL 管道流的关键是把步骤写清楚

PDAL点云处理并不只是“运行一个命令”,更重要的是把数据读取、裁剪、过滤、重投影和输出逻辑写成可复现的管道流。对于 GIS 项目来说,这种方式比手工操作更稳定,也更容易排查问题。

实际配置 PDAL 管道流时,建议先用 pdal info 确认点云范围和坐标系,再从最简单的 reader-writer 管道开始,逐步加入 filters.cropfilters.rangefilters.reprojection 等处理步骤。每增加一个步骤,都检查一次输出范围、点数和坐标系。

只要掌握“输入、过滤、输出”这条主线,PDAL pipeline 就会成为你处理 LAS/LAZ 点云、批量生产数据和搭建自动化 GIS 工作流的可靠工具。