news 2026/8/19 20:23:29

lidR 树冠度量计算:从点云分割到每木属性的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
lidR 树冠度量计算:从点云分割到每木属性的完整指南

lidR 树冠度量计算:从点云分割到每木属性的完整指南

【免费下载链接】lidRAirborne LiDAR data manipulation and visualisation for forestry application项目地址: https://gitcode.com/gh_mirrors/li/lidR

lidR 是 R 语言中面向林业应用的机载 LiDAR 点云处理与可视化工具包,而**树冠度量计算(crown metrics)**是它最强大的功能之一:在完成单木分割后,逐棵计算树高、冠幅面积、点云数量乃至三维形状特征,输出为可直接用于统计建模的空间数据。无论你是林业研究者、遥感初学者还是 GIS 从业者,本指南将带你从零走通"点云 → 树顶检测 → 树冠分割 → 每木属性计算"的完整流程,学会用 crown_metrics 快速产出立木材积、生物量等模型的输入变量。

什么是树冠度量计算?

简单来说,树冠度量计算就是以每一棵树为单位,从点云中提取描述该树的统计指标。与之相对的像素度量(pixel metrics)是把区域切成规则网格、按格子计算指标;而树冠度量更符合林业工作者的思维——关心的是"这棵树多高、冠有多大、有多少点"。

在 lidR 中,这一功能的核心函数是crown_metrics(),它的代码位于 R/metrics_crowns.R。函数签名如下:

crown_metrics(las, func, geom = "point", concaveman = c(3, 0), attribute = "treeID")

其中attribute指定点云中记录树编号的字段(默认treeID),geom决定输出的几何形态,func则是你想为每棵树计算的指标表达式。

准备工作:安装 lidR 并读取点云

开始之前,请确保已安装 lidR 及其依赖:

install.packages("lidR") library(lidR)

使用包自带的示例数据MixedConifer.laz(混合针叶林数据)进行演示,读取时通过-drop_z_below 0过滤掉地面以下的点:

LASfile <- system.file("extdata", "MixedConifer.laz", package = "lidR") las <- readLAS(LASfile, filter = "-drop_z_below 0")

这份数据其实已经完成了单木分割,点云中带有treeID字段,可以直接体验crown_metrics()。不过为了讲清完整流程,我们先从"没有树 ID"的状态出发,一步步构建。

第一步:用 locate_trees 检测单木位置

树冠度量计算的前提是"知道每棵树在哪里"。最常用的方法是用局部最大值滤波(LMF)检测树顶,函数位于 R/locate_trees.R。先构建冠层高度模型(CHM),再在 CHM 上找树顶:

chm <- rasterize_canopy(las, res = 0.5, p2r(0.3)) ttops <- locate_trees(chm, lmf(ws = 5, hmin = 2))

lmf()ws是搜索窗口大小(米),hmin是最低树高阈值。locate_trees()返回一个sf空间点对象,每行代表一棵树,包含树顶坐标和树高Z。窗口大小设置得越接近真实冠幅,检测效果越好;关于窗口与树高关系的细节可参考 R/algorithm-itd.R 中的实现与注释。

第二步:用 segment_trees 分割单木树冠

有了树顶作为"种子",下一步就是把点云按树划开。segment_trees()(见 R/segment_trees.R)配合分割算法使用,最经典的是 Dalponte & Coomes (2016) 的区域生长算法:

las <- segment_trees(las, dalponte2016(chm, ttops))

dalponte2016()是"种子 + 区域生长"算法:从每个树顶出发,按照th_seedth_cr等生长阈值逐步吸收相邻像素,最终形成树冠多边形,再映射回点云。其 C++ 实现位于 R/algorithm-its.R,速度比原始 R 版本快几个数量级。

分割完成后,点云就多了一列treeID,每棵树的点有了唯一编号:

plot(las, color = "treeID")

其他可选算法还有li2012()silva2016()watershed(),以及基于点云的li2012变体,可根据数据特点选择。分割参数影响较大,建议先在小区块上尝试,再用LAScatalog批量处理。

第三步:用 crown_metrics 计算每木属性

现在万事俱备,可以计算每棵树的属性了。最简单的方式是使用内置标准度量.stdtreemetrics,它返回树高Z、点数npoints和凸包面积convhull_area

metrics <- crown_metrics(las, .stdtreemetrics)

metrics是一个sf对象,每一行对应一棵树。直接在控制台查看前几行:

head(metrics)

你还可以自己写度量表达式。例如想同时知道树高和 85% 分位高度:

metrics <- crown_metrics(las, ~list(maxz = max(Z), q85 = quantile(Z, 0.85)))

度量表达式可任意组合,ZIntensityReturnNumber等点云字段都能参与计算,代码实现参考 R/metrics_template.R 中的template_metrics()

四种树冠几何形态:点、凸包、凹包、包围盒

geom参数控制输出几何,是树冠度量计算中最灵活的部分:

  • geom = "point"(默认):输出树顶位置点,包含树高信息;
  • geom = "convex":输出凸包多边形,即包围树冠点的最小凸多边形;
  • geom = "concave":输出凹包多边形,更贴合真实冠形,可通过concaveman = c(3, 0)调节凹凸程度;
  • geom = "bbox":输出轴对齐包围盒矩形。
crown_metrics(las, .stdtreemetrics, geom = "convex") # 凸包 crown_metrics(las, .stdtreemetrics, geom = "concave") # 凹包 crown_metrics(las, .stdtreemetrics, geom = "bbox") # 包围盒

凸包/凹包的面积可直接作为冠幅面积,包围盒则适合快速估算冠幅上下限。几何构造代码见 R/metrics_stdmetrics.R 中的stdtreeapexstdtreehullconvex等内部函数。

用 stdshapemetrics 分析树冠三维形状

除了高度和面积,树冠的三维形状对森林结构研究也很有价值。lidR 提供.stdshapemetrics,基于点云协方差矩阵的特征值分解,计算线性度、平面度、球状度、各向异性等 9 个形状指标(参考 Lucas et al. 2019):

shape <- crown_metrics(las, .stdshapemetrics)

例如linearity(线性度)反映树冠是否呈细长状,sphericity(球状度)反映树冠接近球体的程度,curvature(曲率)可用于区分针叶与阔叶树种。这些指标是机器学习和生态学研究的高质量特征。

自定义度量:写出你的每木指标函数

内置度量不够用时,可以定义任意函数。比如计算强度加权平均高:

myCrownMetrics <- function(z, i) { list( zmax = max(z), zwimean = sum(z * i) / sum(i), # 强度加权平均高 crown_area = length(z) # 点数作为冠幅代理 ) } metrics <- crown_metrics(las, myCrownMetrics(Z, Intensity))

函数返回的命名列表会自动成为输出表的列。这一机制与pixel_metricscloud_metrics等共享同一套模板引擎,官方文档见 man/aggregate.Rd。

大规模区域:LAScatalog 上的树冠度量计算

面对整片林场级别的海量数据,crown_metrics()同样支持LAScatalog对象(见 R/engine.R 的目录引擎),自动分块并行处理并合并结果:

ctg <- readLAScatalog("path/to/laz/files/") metrics <- crown_metrics(ctg, .stdtreemetrics, geom = "convex")

目录引擎会智能切块、自动处理块间缓冲以避免树冠被切开,处理时自动合并输出,具体机制可查看 R/catalog_apply.R 与 R/engine_chunks.R。这是 lidR 从"实验室工具"走向"生产环境"的关键能力。

常见问题与排查技巧

  • 报错 "The trees are not segmented yet":说明点云还没有treeID,先运行segment_trees()
  • 返回 NULL 并提示 "No tree found":分割参数过严或数据中没有符合条件的树,可调低hmin、放宽th_seed
  • 凹包出现无效多边形concave模式下偶发的边界情况会触发警告并自动剔除,属正常现象;
  • ID 不唯一:分块处理时可用uniqueness = "gpstime""bitmerge"生成全局唯一树 ID。

总结

通过locate_trees()检测树顶、segment_trees()分割树冠、crown_metrics()计算每木属性,lidR 把"从点云到每木属性"这条经典林业分析链路压缩成了三行代码。配合四种几何形态、内置标准度量与自定义函数,以及LAScatalog的海量数据支撑,树冠度量计算可以轻松覆盖从单木研究到区域清查的各种场景。现在就加载一份数据试试吧,下一篇文章我们将探讨如何把这些每木属性用于生物量建模与碳储量估算。

快速回顾:① 读点云 → ② 建 CHM 找树顶 → ③ 分割树冠得到 treeID → ④ crown_metrics 计算属性 → ⑤ 导出为 sf 空间数据用于建模分析。

【免费下载链接】lidRAirborne LiDAR data manipulation and visualisation for forestry application项目地址: https://gitcode.com/gh_mirrors/li/lidR

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/19 20:22:12

终极Godot逆向工程指南:用GDRE Tools快速恢复源码、提取PCK资源

终极Godot逆向工程指南&#xff1a;用GDRE Tools快速恢复源码、提取PCK资源 【免费下载链接】gdsdecomp Godot reverse engineering tools 项目地址: https://gitcode.com/GitHub_Trending/gd/gdsdecomp 如果你正在寻找一套能够对 Godot 游戏进行逆向工程的专业工具&…

作者头像 李华
网站建设 2026/8/19 20:15:22

35B量化大模型本地部署实战:从选版本到跑通全流程

35B量化大模型本地部署实战&#xff1a;从选版本到跑通全流程 【免费下载链接】Qwen3.6-35B-A3B-APEX-GGUF 项目地址: https://ai.gitcode.com/hf_mirrors/mudler/Qwen3.6-35B-A3B-APEX-GGUF 先把话说在前面&#xff1a;这篇文章是写给谁看的&#xff1f;如果你刚拿到一…

作者头像 李华