Tree separation test — segment_085 annotated Tree.e57

2026-08-27 · technical (AI3D vegetation / tree instances) · generated by Claude

Summary

Input: the human-annotated class-5 5 Tree.e57 (207k points, RGB) from …/260812_full_sweep/branch_000/segment_085/reCap export_classfied_v2, with 2 Terén.e57 as ground. The splitter (tree_instances.split_tree_cluster, default config) produced 20 tree instances, but only 3 are stem-seeded; the other 17 come from the crown-apex fallback.

verdict The annotated "Tree" class is 99 % one continuous canopy blob (35 m radius) whose median height above ground is 2.4 m (p95 5.2 m). Real crowns with trunks exist only on the east/upper side; the rest is a low, sparse thicket that the apex fallback tiles into ~5–10 m instances with no tree behind them. Split is geometrically plausible where trees exist, arbitrary elsewhere.

Images

Top-down, world XY (EPSG as in the E57, metres). Click/zoom for detail — each image is ~2400 px wide.

Top-down view of tree points coloured by instance id, seeds marked with X
Instances. One tab20 colour per tree_instance_id; grey = abstain (unreachable / low evidence / too small); X = seed with true-scale stem circle; label nS = stem seed, nA = crown-apex seed.
Top-down view coloured by height above ground, seeds as X
Height above ground (2 m-cell min-z DTM from the Terén class), 0–8 m colour scale, seeds as X. Only the upper-right area (x ≈ 696 895–905) reaches 5–7.5 m; most of the class sits at 1–4 m.
Side elevation of the tree points, x versus height above ground, instance colours
Side view (x vs height, looking north). Scan-line striping shows the sparse coverage; canopy height rises from ~3 m in the west to ~7 m in the east.

Orbit video

44 s, 1600×900: 12 s overview orbit + four 8 s close-ups (east stem-seeded trees 14S/17S/16A · south apex-tiled thicket 7A/10A/11S · NW crowns 4A/6A/8A · west 0A–3A). Instance colours as above, ground dark grey.

On N: 02_Modelling\05_Rink\02_AI 3D modeling\02_OUT\260716_videos\260827_ReCap_segment_085_tree_instances\260827_segment_085_tree_instances_orbit.mp4 (78 MB, + preview and top-down PNG alongside). Renderer: out_trees/annot085/orbit.py.

Numbers

stepresult
Tree class points206 969 (RGB present, ExG usable)
Blobs (3-D DBSCAN eps 1.0 m, min 8)9 blobs + 97 noise pts; blob 0 = 205 645 pts (99 %), footprint radius ≈ 35 m, max height 8.8 m
Splitter verdict, blob 0merged → 19 instances (3 stem, 16 apex); 180 289 pts assigned
Other blobs1 × single (523 pts, 5.3 m); 3 × uncertain, 0 seeds (183 / 393 / 63 pts)
Points assigned180 812 / 206 969 (87 %)
Abstentions19 137 unreachable · 6 402 low evidence · 393 no stem seed · 128 too small
Height above DTMp5 0.8 m · median 2.4 m · p95 5.2 m · max 7.6 m

How to read it

Method

  1. Read E57 with pye57 → XYZ + RGB; ExG = (2g − r − b)/(r + g + b) via scripts/tree_instance_split.compute_exg.
  2. Cluster into "detections": 3-D DBSCAN (eps 1.0 m, min_samples 8) — stand-in for the detector's cluster step.
  3. Per blob: z_ground = 5th percentile of Terén-class z within blob footprint + 3 m; call split_tree_cluster(xyz, z_ground, exg, DetectorConfig()); offset labels to global ids.
  4. Render with tree_instance_render.instance_colors palette; DTM for the height panel = 2 m cell min-z of the ground class.
uv run python out_trees/annot085/run_split.py 1.0   # → /tmp/tree085/{split.npz,split_summary.json,trees_topdown.png}
uv run python out_trees/annot085/render2.py          # 3-panel PNG

Sources kept in out_trees/annot085/ (git-ignored) and /tmp/tree085/; page assets in docs/pages/tree-split-085-20260827_assets/.

Next (not run)