Clicky

8  Quantitative Structure Forest

A Quantitative Structure Model (QSM) is a three-dimensional representation of a single individual tree that explicitly describes its geometry and topology (stems, branches, radii, volumes). QSMs provide a physically meaningful model, rather than a purely statistical description.

In this book, we extend this concept from individual trees to entire forests by introducing the Quantitative Structure Forest (QSF). A QSF is a coherent collection of QSMs that together reconstruct the three-dimensional structure of all trees within a forested area.

This conceptual extension is made possible by our advances in QSM algorithms that are fast and robust enough to reconstruct tens of thousands of trees, enabling full 3D modelling of forests spanning several hectares. The QSF concept bridges the gap between tree-level and forest-level analysis, providing a unified framework to study tree architecture, stand structure, competition, biomass distribution, and canopy organisation within a single 3D representation.

8.1 Building a QSF

Building a QSF is relatively straightforward. Users could simply loop over all trees and compute a QSM for each one. Arbor includes a function, qsf(), that performs this task in parallel and in an optimized manner.

As described in previous chapters, the variable las contains the segmented scene.

qsf = qsf(las)

The qsf function is blazingly fast and can produce several hundred QSMs per minute! qsf() computes one QSM per tree but excludes trees that are in the buffer zone (see flag_buffer() in Section 6.6) or that are flagged as low understory (see flag_small_trees() in Section 6.5). This makes sense since flag_* functions are designed to exclude trees for which we cannot obtain good results.

Tip

A qsf object is simply a list with an additional class to enable convenient printing and plotting methods. Thus, qsf[[1]] contains a qsm object.

qsf() does not throw any warnings because, on a typical 1/4-hectare plot with 400 saplings and 200 young trees, this would generate at least 600 warnings. This is unmanageable. Indeed, qsm() warns about non-measurable young trees. Instead, all QSMs record a message. Users can call qsf_log() to obtain a summary of troubleshooting.

Be careful: by default, qsf() produces a QSM for every instance taller than 2 m. This can create a large number of QSMs with negligible volume, which is not always desirable. The function provides a parameter to control this threshold e.g. qsf(las, min_height = 4).

8.2 What to Do with a QSF?

8.2.1 3D Rendering

The first thing we can do with a QSF is render it in 3D within R.

plot(qsf, pal = "chocolate4") |> lidR::add_dtm3d(dtm)

3D rendering of a QSF. QSF computed in 4 seconds

3D rendering of a QSF. QSF computed in 4 seconds

8.2.2 Tree Map & Volume Inventory

A QSF can also be used to perform complete forest inventories, producing a tree map with detailed information for each tree, such as basal area, volume, height, and other structural attributes.

tm <- qsf_treemap(qsf)

A tree map with volume displayed (trees are scaled ×2 for rendering)

A tree map with volume displayed (trees are scaled ×2 for rendering)

8.2.3 Export to 3D Software

The qsf() function includes an option to export all trees into separate folders. Users can also use qsf_write() to export individual trees to formats such as .qsm, .obj, .stl, .ply, .csv or other formats supported by 3D software. For example, Blender can be used as an open-source solution for realistic rendering while CloudCompare can be use for casual rendering.

Rendering with Blender

Rendering with Blender

8.2.4 Reclassifying Wood and Foliage

Warning

This feature is experimental; it may or may not be removed in future versions.

Our semantic segmentation is not perfect. It intentionally over-segments in order to ensure that the entire tree branching structure is captured. As a result, this approach produces numerous false positives in foliage (by design) and some false negatives (not by design). The semantic segmentation is therefore not intended for direct scientific use; it is primarily designed to support QSM reconstruction.

With a QSF, it becomes possible to reclassify points based on each individual QSM. This reclassification can be useful for downstream analyses such as estimating Plant Area Index (PAI) or Leaf Area Index (LAI), where a more accurate separation between wood and foliage is required.

las = qsf_segment_semantic(las, qsf)

Raw semantic segmentation (left) and post-processing using QSMs and a QSF (right)

Raw semantic segmentation (left) and post-processing using QSMs and a QSF (right)

8.2.5 Merchandable Volume

See Chapter 9 for more information about forestry operations.

8.3 Code

8.3.1 Function list

  • qsf() to build a QSF
  • qsf_write() for saving the QSMs in .obj, .ply .csv or .qsm for analyzing or for rendering in 3D software.
  • qsf_treemap() for saving forest in GIS vector files
  • qsf_segment_semantic() for more accurate semantic segmentation
  • qsf_merchantable() (see Chapter 9)
  • plot() for 3D rendering

8.3.2 Full Code

library(lidR)
library(arbor)

params <- arbor_parameters_default
params$global$cut_above_ground = 0.25
filter <- "-keep_random_fraction 0.25"
buffer <- 5

las <- readTLS(file, select = "xyz", filter = filter)

las <- hybrid_homogeneization(las)
las <- segment_ground(las)
las <- wood_likelihood(las, params)
las <- segment_semantic(las, params)
see <- find_seeds(las, params)
las <- segment_instance(las, see, params)
las <- flag_small_trees(las, max_height = 2)
las <- flag_buffer(las, see, -buffer)
qsf <- qsf(las, params = params)
plot(qsf)