You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用while循环统计lidR分割树木点数量仅获首棵树数据的问题

问题原因

你代码的核心问题是每次循环都覆盖了原始的las对象:
第一次执行las <- filter_poi(las, treeID == 1)后,las就只剩treeID=1的点云数据了。后续循环i=2、3...时,在这个已经被过滤的las里根本找不到对应treeID的点,自然只能得到错误结果。

解决方案

方案1:修复循环逻辑(不推荐,效率低)

保留原始点云对象,每次基于原始数据过滤,不要修改原始las:

las <- segment_trees(las, watershed(chm, th_tree = 1, tol = 0.5, ext = 2))

# 先保存原始点云,避免被覆盖
original_las <- las
pointlist <- list()

# 先获取所有存在的treeID,避免循环到不存在的ID(比固定循环到1000更合理)
all_treeIDs <- unique(original_las$treeID)

for (tree_id in all_treeIDs) {
  current_las <- filter_poi(original_las, treeID == tree_id)
  point_count <- nrow(current_las)  # 直接用nrow获取点数,比读header更简单
  pointlist[[as.character(tree_id)]] <- point_count
}

pointlist

方案2:高效分组统计(强烈推荐)

R是向量式语言,用分组统计替代循环效率高得多,lidR和常用工具包都有现成方法:

方法A:用lidR自带的tree_metrics

专门针对treeID分组计算指标,最贴合lidR工作流:

las <- segment_trees(las, watershed(chm, th_tree = 1, tol = 0.5, ext = 2))

# 按treeID统计点数,结果是带treeID和n_points的LAS对象(或数据框)
tree_point_counts <- tree_metrics(las, ~list(n_points = .N))

方法B:用dplyr分组统计

如果习惯tidyverse语法:

library(dplyr)

las <- segment_trees(las, watershed(chm, th_tree = 1, tol = 0.5, ext = 2))

las_df <- as.data.frame(las)
tree_point_counts <- las_df %>% 
  group_by(treeID) %>% 
  summarise(n_points = n())

方法C:用base R的table函数

最简单快速的方式,返回treeID和对应点数的表格:

las <- segment_trees(las, watershed(chm, th_tree = 1, tol = 0.5, ext = 2))

tree_point_counts <- table(las$treeID)

内容的提问来源于stack exchange,提问作者Purple_Ad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 20:15:34