Skip to content

Repository files navigation

🌲 points2SBL

Toward Operational Wildfire Fuel Mapping: Sensor-Agnostic Deep Learning Semantic Segmentation of Terrestrial LiDAR Across Global Forest Ecosystems

Python PyTorch CUDA Platform License Paper

points2SBL processing pipeline

points2SBL is an open-source framework for binary semantic segmentation of forest LiDAR point clouds into woody and foliar components. The current release is designed to make pretrained-model inference straightforward for plot-scale and individual-tree point clouds while retaining the complete data-preparation and training workflow for advanced users.

The research behind points2SBL is now available as a preprint, providing the scientific basis for our deep-learning approach to wood–foliar semantics of forest LiDAR point clouds https://www.preprints.org/manuscript/202608.0737

The recommended production model is the Point Transformer. PointNeXt and PointNet++ remain available for comparison, ablation, and alternative deployment requirements.


Highlights

Capability Support
Wood–leaf segmentation
Point Transformer ✅ Recommended
TLS plots
MLS / BLS / PLS
ULS
CPU and CUDA execution
Single-file inference
Recursive folder inference
Automatic plot/tree detection
Multi-vote probability aggregation
Spatial confidence weighting
Woody-structure refinement
Prediction probability export
JSON inference sidecars

Installation

points2SBL can be installed from PyPI, GitHub, or used in Google Colab.

USE: https://www.anaconda.com/download

Recommended: Python 3.11 and a CUDA-enabled PyTorch installation for local GPU inference.


Option 1 — PyPI

Create an environment:

conda create -n points2sbl python=3.11 -y
conda activate points2sbl

Install the validated CUDA build of PyTorch:

python -m pip install `
  torch==2.5.1 `
  torchvision==0.20.1 `
  torchaudio==2.5.1 `
  --index-url https://download.pytorch.org/whl/cu121

Install points2SBL:

pip install points2sbl

Download and verify the pretrained model:

points2sbl model download
points2sbl model status

Option 2 — GitHub

git clone https://github.com/nadeemfareed/points2SBL.git
cd points2SBL

conda create -n points2sbl python=3.11 -y
conda activate points2sbl

Install PyTorch:

python -m pip install `
  torch==2.5.1 `
  torchvision==0.20.1 `
  torchaudio==2.5.1 `
  --index-url https://download.pytorch.org/whl/cu121

Install points2SBL:

python -m pip install -e .

Download and verify the pretrained model:

points2sbl model download
points2sbl model status

Option 3 — Google Colab

points2SBL can run directly in Google Colab with GPU acceleration. This is a convenient option for users who do not have a local CUDA-enabled GPU.

Python 3.13 note: points2SBL v0.3.1 currently declares Python >=3.10,<3.13, while newer Google Colab runtimes may use Python 3.13. Until Python 3.13 support is officially included in the next release, Colab users can install the current release using --ignore-requires-python.

1. Enable a GPU

In Google Colab, select:

Runtime → Change runtime type → Hardware accelerator → GPU

Then verify the runtime:

import sys
import torch

print("Python:", sys.version)
print("PyTorch:", torch.__version__)
print("CUDA available:", torch.cuda.is_available())

if torch.cuda.is_available():
    print("GPU:", torch.cuda.get_device_name(0))

A typical GPU-enabled Colab runtime should report:

CUDA available: True
GPU: Tesla T4

Colab already provides a CUDA-enabled PyTorch installation. Do not replace the Colab PyTorch build unless necessary.


2. Install points2SBL

Install the current PyPI release:

!pip install --ignore-requires-python points2sbl

Download and verify the released pretrained Point Transformer:

!points2sbl model download
!points2sbl model status

The model is downloaded to:

/content/runs/point_transformer_curated_20260327_170108/best.pt

--ignore-requires-python is a temporary workaround for points2SBL v0.3.1 on Python 3.13. It can be removed after a points2SBL release officially declares Python 3.13 support.


3. Mount Google Drive

Mount Google Drive so points2SBL can access your LAS/LAZ files:

from google.colab import drive

drive.mount("/content/drive")

Your main Google Drive directory will normally be:

/content/drive/MyDrive/

For example, if your point cloud is:

MyDrive/forest_plot.las

its Colab path is:

/content/drive/MyDrive/forest_plot.las

4. Download the points2SBL configuration

The PyPI installation provides the executable package. Clone the repository to obtain the standard configuration files and examples:

!git clone -q https://github.com/nadeemfareed/points2SBL.git /content/points2SBL

Define the model and configuration paths:

CFG = "/content/points2SBL/configs/point_transformer.yaml"
CKPT = "/content/runs/point_transformer_curated_20260327_170108/best.pt"

print("Config:", CFG)
print("Model :", CKPT)

5. Select an input LAS/LAZ file

Set the input and output paths.

Example:

INPUT = "/content/drive/MyDrive/forest_plot.las"
OUTPUT = "/content/drive/MyDrive/forest_plot_points2SBL.las"

print("Input :", INPUT)
print("Output:", OUTPUT)

Check that the input exists:

from pathlib import Path

assert Path(INPUT).exists(), f"Input file not found: {INPUT}"
print("Input file found.")

6. Run forest-plot inference

For a forest plot or multi-tree point cloud where existing ground points use LAS Classification = 2:

!points2sbl predict \
  --input_type plot \
  --mode full \
  --config "$CFG" \
  --ckpt "$CKPT" \
  --in_las "$INPUT" \
  --out_las "$OUTPUT" \
  --device cuda \
  --geom_cache all \
  --progress tiles

The classified LAS file will be written directly to Google Drive.


7. Individual-tree inference

For an isolated individual tree without ground, use single_tree:

INPUT = "/content/drive/MyDrive/tree_001.las"
OUTPUT = "/content/drive/MyDrive/tree_001_points2SBL.las"

Then run:

!points2sbl predict \
  --input_type single_tree \
  --mode full \
  --config "$CFG" \
  --ckpt "$CKPT" \
  --in_las "$INPUT" \
  --out_las "$OUTPUT" \
  --device cuda \
  --geom_cache all \
  --progress tiles

For individual trees, points2SBL automatically selects an appropriate tile size from the XY extent of the tree.


8. Higher-quality multi-vote inference

For higher-quality prediction when additional processing time is acceptable:

!points2sbl predict \
  --input_type plot \
  --mode full \
  --config "$CFG" \
  --ckpt "$CKPT" \
  --in_las "$INPUT" \
  --out_las "$OUTPUT" \
  --device cuda \
  --votes 8 \
  --vote_mode hybrid8 \
  --vote_weight confidence \
  --geom_cache all \
  --progress tiles

Multi-vote inference evaluates the point cloud using multiple spatial layouts and aggregates the predictions.


Output classes

For plot-level processing, points2SBL uses:

LAS Classification Semantic class
0 Wood
1 Leaf / needle
2 Ground

Existing class-2 ground points are preserved during plot-level wood–leaf inference.

The output also contains prediction information including:

  • pred_class
  • pred_leaf_prob
  • inference diagnostics in the JSON sidecar

Large point clouds

For large LAS/LAZ files, Google Drive I/O may become a bottleneck. Copying the input to Colab's local storage before inference can improve performance:

import shutil
from pathlib import Path

DRIVE_INPUT = "/content/drive/MyDrive/forest_plot.las"
LOCAL_INPUT = "/content/forest_plot.las"
LOCAL_OUTPUT = "/content/forest_plot_points2SBL.las"
DRIVE_OUTPUT = "/content/drive/MyDrive/forest_plot_points2SBL.las"

shutil.copy2(DRIVE_INPUT, LOCAL_INPUT)

print("Copied input to local Colab storage.")

Run inference locally:

!points2sbl predict \
  --input_type plot \
  --mode full \
  --config "$CFG" \
  --ckpt "$CKPT" \
  --in_las "$LOCAL_INPUT" \
  --out_las "$LOCAL_OUTPUT" \
  --device cuda \
  --geom_cache all \
  --progress tiles

Then copy the completed result back to Google Drive:

shutil.copy2(LOCAL_OUTPUT, DRIVE_OUTPUT)

print("Saved:", DRIVE_OUTPUT)

GPU memory

If a large point cloud exceeds the available GPU memory, reduce the inference batch size:

--batch_blocks 8

If necessary:

--batch_blocks 4

For example:

!points2sbl predict \
  --input_type plot \
  --mode full \
  --config "$CFG" \
  --ckpt "$CKPT" \
  --in_las "$INPUT" \
  --out_las "$OUTPUT" \
  --device cuda \
  --batch_blocks 4 \
  --geom_cache all \
  --progress tiles

Troubleshooting

Check the installation:

!points2sbl --help
!points2sbl model status

Check the available inference options:

!points2sbl predict --help

Check CUDA:

import torch

print("PyTorch:", torch.__version__)
print("CUDA version:", torch.version.cuda)
print("CUDA available:", torch.cuda.is_available())

if torch.cuda.is_available():
    print("GPU:", torch.cuda.get_device_name(0))

Download the pretrained model again if necessary:

!points2sbl model download --force

Quick Colab workflow

For experienced users, the complete workflow is:

# Install points2SBL
!pip install --ignore-requires-python points2sbl

# Download pretrained model
!points2sbl model download

# Obtain configuration files
!git clone -q https://github.com/nadeemfareed/points2SBL.git /content/points2SBL
# Mount Google Drive
from google.colab import drive
drive.mount("/content/drive")
# Set paths
CFG = "/content/points2SBL/configs/point_transformer.yaml"
CKPT = "/content/runs/point_transformer_curated_20260327_170108/best.pt"

INPUT = "/content/drive/MyDrive/forest_plot.las"
OUTPUT = "/content/drive/MyDrive/forest_plot_points2SBL.las"
# Run inference
!points2sbl predict \
  --input_type plot \
  --mode full \
  --config "$CFG" \
  --ckpt "$CKPT" \
  --in_las "$INPUT" \
  --out_las "$OUTPUT" \
  --device cuda \
  --geom_cache all \
  --progress tiles

Inference

points2SBL accepts .las and .laz point clouds.

Use:

  • plot for forest plots or multi-tree scenes.
  • single_tree for isolated trees.
  • full as the recommended inference mode.

Ground classification for forest plots

Important: For forest plots containing terrain, ground classification should be performed before points2SBL inference. Ground points should use the standard LAS Classification = 2.

FAST-GC is recommended for ground classification before points2SBL.

FAST-GC can be installed directly with:

pip install fastgc

For plot-level processing, the recommended order is:

LAS/LAZ point cloud
        ↓
FAST-GC
Ground = Classification 2
        ↓
points2SBL
        ↓
Wood = 0 | Leaf = 1 | Ground = 2

See the FAST-GC repository for the current recommended TLS ground-classification command and usage.

FAST-GC preprocessing is not required for isolated individual-tree point clouds that do not contain ground.


Forest plot — recommended

Use this configuration for routine plot processing.

points2sbl predict `
  --input_type plot `
  --mode full `
  --config ".\configs\point_transformer.yaml" `
  --ckpt ".\runs\point_transformer_curated_20260327_170108\best.pt" `
  --in_las "D:\input\forest_plot.las" `
  --out_las "D:\output\forest_plot_points2sbl.las" `
  --device cuda `
  --geom_cache all `
  --progress tiles

Forest plot — maximum quality

Use this configuration when prediction quality is preferred over processing time.

points2sbl predict `
  --input_type plot `
  --mode full `
  --config ".\configs\point_transformer.yaml" `
  --ckpt ".\runs\point_transformer_curated_20260327_170108\best.pt" `
  --in_las "D:\input\forest_plot.las" `
  --out_las "D:\output\forest_plot_HYBRID8_V10.las" `
  --device cuda `
  --votes 10 `
  --vote_mode hybrid8 `
  --vote_weight confidence `
  --geom_cache all `
  --progress tiles

This was the highest-performing configuration in our validation tests.


Forest plot — faster multi-vote

For large datasets, four deterministic votes provide a useful quality/runtime compromise.

points2sbl predict `
  --input_type plot `
  --mode full `
  --config ".\configs\point_transformer.yaml" `
  --ckpt ".\runs\point_transformer_curated_20260327_170108\best.pt" `
  --in_las "D:\input\forest_plot.las" `
  --out_las "D:\output\forest_plot_GRID4_V4.las" `
  --device cuda `
  --votes 4 `
  --vote_mode grid4 `
  --vote_weight confidence `
  --geom_cache all `
  --progress tiles

Individual tree

Use single_tree for isolated trees. Tile size is selected automatically.

points2sbl predict `
  --input_type single_tree `
  --mode full `
  --config ".\configs\point_transformer.yaml" `
  --ckpt ".\runs\point_transformer_curated_20260327_170108\best.pt" `
  --in_las "D:\input\tree_001.las" `
  --out_las "D:\output\tree_001_points2sbl.las" `
  --device cuda `
  --geom_cache all `
  --progress tiles

Batch processing

Forest plots

For plot datasets containing terrain, perform ground classification with FAST-GC before running the batch.

points2sbl predict `
  --input_type plot `
  --mode full `
  --config ".\configs\point_transformer.yaml" `
  --ckpt ".\runs\point_transformer_curated_20260327_170108\best.pt" `
  --in_dir "D:\input\forest_plots" `
  --out_dir "D:\output\forest_plots_points2sbl" `
  --recursive `
  --skip_existing `
  --device cuda `
  --geom_cache all `
  --progress tiles

Individual trees

points2sbl predict `
  --input_type single_tree `
  --mode full `
  --config ".\configs\point_transformer.yaml" `
  --ckpt ".\runs\point_transformer_curated_20260327_170108\best.pt" `
  --in_dir "D:\input\single_trees" `
  --out_dir "D:\output\single_trees_points2sbl" `
  --recursive `
  --skip_existing `
  --device cuda `
  --geom_cache all `
  --progress tiles

Output classes

Classification Class
0 Wood
1 Leaf / needle
2 Ground, when present

The output point cloud also contains prediction information including pred_class and pred_leaf_prob.


Troubleshooting

Check installation

points2sbl --help
points2sbl model status

CUDA is unavailable

Check the installed PyTorch build:

python -c "import torch; print(torch.__version__); print(torch.version.cuda); print(torch.cuda.is_available())"

If torch.cuda.is_available() returns False, install a CUDA-enabled PyTorch build.

Download the model again

points2sbl model download --force

GPU out of memory

Reduce the inference batch size:

--batch_blocks 8

If necessary:

--batch_blocks 4

Help

View all available command-line options with:

points2sbl predict --help

Output

The output LAS/LAZ preserves the original point geometry and supported LAS attributes while adding prediction information.

Attribute Meaning
Classification Final class when classification overwrite is enabled
pred_class Binary predicted class
pred_leaf_prob Aggregated probability of the leaf class
JSON sidecar Resolved settings and inference diagnostics

Advanced inference controls

The public interface intentionally keeps common workflows simple. Advanced parameters remain available for expert experiments.

Voting

--votes
--vote_mode {grid4,grid8,hybrid8,random}
--vote_weight {uniform,confidence}

Geometry cache

--geom_cache {none,all}

all computes geometric features once for the prediction points and reuses them during inference.

Full-mode refinement

Advanced controls include:

--t_low
--t_high
--geom_rescue_thr
--local_woody_thr
--local_leaf_thr
--smooth_k
--smooth_tau
--woody_refine_k
--woody_core_p_leaf_max
--woody_structure_k

Adaptive mode

Advanced adaptive parameters include:

--adaptive_hist_bins
--adaptive_hist_smooth_sigma
--adaptive_shoulder_fraction
--adaptive_min_transition_width
--adaptive_geom_ratio
--adaptive_local_support_min

Most users should use the mode defaults rather than changing these parameters.


Performance notes

The current Point Transformer inference implementation reuses shared neighborhood information inside the model to reduce redundant computation during inference.

Runtime depends on:

  • total number of points;
  • tile size;
  • number of overlapping layouts/votes;
  • number of model blocks;
  • geometric-feature computation;
  • semantic refinement;
  • GPU capability;
  • disk speed.

On CUDA-capable systems, points2SBL automatically limits the default inference batch on lower-VRAM GPUs to reduce out-of-memory failures. Explicit --batch_blocks values override the automatic choice.


Troubleshooting

CUDA requested but unavailable

Check:

python -c "import torch; print(torch.__version__); print(torch.version.cuda); print(torch.cuda.is_available())"

A CUDA-capable GPU and driver are not sufficient by themselves; PyTorch must also be installed with CUDA support.

Editable installation replaced CUDA PyTorch

Install the desired CUDA PyTorch build first, then reinstall points2SBL without dependencies:

python -m pip install -e . --no-deps

OpenMP conflict on Windows

An error such as:

OMP: Error #15: Initializing libomp.dll, but found libiomp5md.dll already initialized

means multiple OpenMP runtimes were loaded.

The preferred solution is to remove conflicting package builds and use a clean, consistent environment.

The following workaround may allow execution but is not recommended for production:

$env:KMP_DUPLICATE_LIB_OK = "TRUE"
```.
## Automatic input detection is inappropriate

Override it explicitly:

```powershell
--input_type plot

or:

--input_type single_tree

Need the unrefined network result

Use:

--mode raw

Need probability-distribution-driven thresholding

Use:

--mode adaptive

GPU out of memory

Reduce:

--batch_blocks 8

or:

--batch_blocks 4

Keep the checkpoint-compatible number of points per block unless intentionally testing another model configuration.

Resume an interrupted folder run

Use:

--skip_existing

Previously completed outputs are skipped and the remaining files are processed.


Results gallery

The image paths below intentionally retain the existing repository filenames.

Training datasets

Training datasets

Representative labeled forest point clouds used for model development.

Benchmark datasets

Benchmark datasets

Independent datasets used to assess segmentation accuracy and transferability.

Model performance

Model performance

Comparative performance of Point Transformer, PointNet++, and PointNeXt.

Tropical forest generalization

Tropical forest predictions

Wood–leaf prediction on structurally complex tropical trees not used during training.

Lin3D benchmark

Lin3D prediction

Reference labels and Point Transformer predictions for complex plot-level forest scenes.

Large registered TLS plot

Registered TLS plot

Large-scale registered TLS prediction processed through block-wise multi-vote inference.

ULS prediction

ULS prediction

Prediction on lower-density ULS data.

BlueCat qualitative result

BlueCat prediction

Prediction on the structurally complex BlueCat TLS dataset.

BlueCat reference, prediction, probability, and disagreement

BlueCat probability disagreement

Reference labels, final prediction, leaf probability, and probability disagreement shown from complementary views.

Keep the corresponding PNG files under docs/images/. If GitHub filenames differ, update the paths above to match the repository exactly.


Advanced: data preparation

Most users using the released pretrained model can skip this section.

The transferable training workflow uses a common block representation across TLS, MLS, ULS, plot clouds, and individual trees.

Mixed-sensor training corpus

Example layout:

D:\points2SBL_training_raw\
├── TLS_plots\
├── TLS_single_trees\
├── MLS\
└── ULS\

Prepare the combined corpus:

python -u -m points2sbl.prepare_data `
  --config "configs\point_transformer.yaml" `
  --data_root "D:\points2SBL_training_raw" `
  --recursive `
  --label_field Classification `
  --leaf_class 1 `
  --xy_size 2.0 2.0 `
  --stride 1.0 1.0 `
  --n_points 8192 `
  --min_points 64 `
  --val_ratio 0.20 `
  --rotate_train `
  --save_format npz

TLS plot preparation

python -u -m points2sbl.prepare_data `
  --config "configs\point_transformer.yaml" `
  --data_root "D:\training\TLS_plots" `
  --recursive `
  --label_field Classification `
  --leaf_class 1 `
  --xy_size 2.0 2.0 `
  --stride 1.0 1.0 `
  --n_points 8192 `
  --min_points 64 `
  --val_ratio 0.20 `
  --rotate_train `
  --save_format npz

MLS / BLS / PLS preparation

python -u -m points2sbl.prepare_data `
  --config "configs\point_transformer.yaml" `
  --data_root "D:\training\MLS" `
  --recursive `
  --label_field Classification `
  --leaf_class 1 `
  --xy_size 2.0 2.0 `
  --stride 1.0 1.0 `
  --n_points 8192 `
  --min_points 64 `
  --val_ratio 0.20 `
  --rotate_train `
  --save_format npz

ULS preparation

A larger block can be used when building a dedicated lower-density ULS model:

python -u -m points2sbl.prepare_data `
  --config "configs\point_transformer.yaml" `
  --data_root "D:\training\ULS" `
  --recursive `
  --label_field Classification `
  --leaf_class 1 `
  --xy_size 3.0 3.0 `
  --stride 1.5 1.5 `
  --n_points 8192 `
  --min_points 64 `
  --val_ratio 0.20 `
  --rotate_train `
  --save_format npz

Individual-tree preparation

For a dedicated individual-tree training corpus:

python -u -m points2sbl.prepare_data `
  --config "configs\point_transformer.yaml" `
  --data_root "D:\training\single_trees" `
  --recursive `
  --label_field Classification `
  --leaf_class 1 `
  --xy_size 5.0 5.0 `
  --stride 2.5 2.5 `
  --n_points 8192 `
  --min_points 64 `
  --val_ratio 0.20 `
  --rotate_train `
  --save_format npz

Prepared datasets typically contain:

<data_root>/
├── train/
├── val/
├── test/                 # when requested
└── _prepare_report.json

Before training, inspect _prepare_report.json and confirm that files, classes, and train/validation blocks were created as expected.


Advanced: training

Most users using the released checkpoint can skip this section.

Point Transformer is the recommended production architecture. PointNeXt and PointNet++ are retained for comparison and experimentation.

Point Transformer

python -u -m points2sbl.train `
  --config "configs\point_transformer.yaml" `
  --data_root "D:\points2SBL_training_raw" `
  --out_dir "runs\point_transformer_mixed_sensors" `
  --device cuda

PointNeXt

python -u -m points2sbl.train `
  --config "configs\pointnext.yaml" `
  --data_root "D:\points2SBL_training_raw" `
  --out_dir "runs\pointnext_mixed_sensors" `
  --device cuda

PointNet++

python -u -m points2sbl.train `
  --config "configs\pointnet2.yaml" `
  --data_root "D:\points2SBL_training_raw" `
  --out_dir "runs\pointnet2_mixed_sensors" `
  --device cuda

A training run typically produces:

runs/<run_name>/
├── best.pt
├── last.pt
├── config_resolved.json
├── metrics.jsonl
└── train.log

Use best.pt for production inference unless a specific experiment requires another checkpoint.



Generated caches, build directories, local checkpoints, temporary patches, and prediction outputs should not be committed to Git.

---

# Citation

If you use points2SBL, please cite the accompanying manuscript:

```bibtex
@article{Nadeem2026points2SBL,
  title   = {Toward Operational Wildfire Fuel Mapping: Sensor-Agnostic Deep Learning Semantic Segmentation of Terrestrial LiDAR Across Global Forest Ecosystems},
  author  = {Nadeem, Fareed et al.},
  journal = {Remote Sensing},
  year    = {2026},
  note    = {Under review}
}

License

points2SBL is released under the GNU General Public License v3.0 (GPL-3.0). See LICENSE for details..


Contact

Fareed Nadeem
School of Forest, Fisheries, and Geomatics Sciences
University of Florida
nadeem@geomatics.ncku.edu.tw fareed.nadeem@ufl.edu

GitHub: nadeemfareed

points2SBL — pretrained inference first, reproducible training when needed

About

Toward operational wildfire fuel mapping: sensor-agnostic deep learning semantic segmentation of terrestrial LiDAR across global forest ecosystems.

Resources

Contributing

Security policy

Stars

22 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages