Skip to content

Download notebook

Tree Crown Delineation with detectree2

image

This notebook demonstrates how to use the detectree2 module for automatic tree crown delineation in aerial RGB imagery using Mask R-CNN.

Overview

detectree2 is a Python package for automatic tree crown delineation based on the Detectron2 implementation of Mask R-CNN. It has been designed to delineate trees in challenging dense tropical forests and has been validated across various forest types.

Reference: Ball, J.G.C., et al. (2023). Accurate delineation of individual tree crowns in tropical forests from aerial RGB imagery using Mask R-CNN. Remote Sens Ecol Conserv. 9(5):641-655. https://doi.org/10.1002/rse2.332

Installation

First, install the required packages. detectree2 requires PyTorch and Detectron2 to be installed first.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Install PyTorch (adjust for your CUDA version)
# %pip install torch torchvision

# Install Detectron2
# %pip install 'git+https://github.com/facebookresearch/detectron2.git'

# Install detectree2
# %pip install git+https://github.com/PatBall1/detectree2.git

# Install segment-geospatial
# %pip install segment-geospatial

Import Libraries

1
2
3
4
5
import leafmap
from samgeo.detectree2 import (
    TreeCrownDelineator,
    list_pretrained_models,
)

List Available Pre-trained Models

detectree2 provides several pre-trained models from different forest types:

1
2
3
models = list_pretrained_models()
for name, url in models.items():
    print(f"{name}: {url}")

Download Sample Image

Download a sample tree image for testing:

1
2
3
4
image_url = (
    "https://github.com/opengeos/datasets/releases/download/samgeo/tree_image.tif"
)
image_path = leafmap.download_file(image_url)

Visualize the Sample Image

1
2
3
m = leafmap.Map()
m.add_raster(image_path, layer_name="Tree Image")
m

Initialize the Tree Crown Delineator

Initialize the TreeCrownDelineator with a pre-trained model. The model will be automatically downloaded on first use.

1
2
3
4
5
delineator = TreeCrownDelineator(
    model_name="default",  # Options: 'paracou', 'sepilok', 'danum', 'default'
    confidence_threshold=0.5,  # Minimum confidence for predictions
    nms_threshold=0.3,  # Non-maximum suppression threshold
)

Predict Tree Crowns

Run the prediction on the sample image:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
output_path = "tree_crowns.gpkg"

crowns = delineator.predict(
    image_path=image_path,
    output_path=output_path,
    tile_width=20,  # Tile width in meters
    tile_height=20,  # Tile height in meters
    buffer=30,  # Buffer around tiles in meters
    simplify_tolerance=0.2,  # Simplify crown geometries
    min_confidence=0.3,  # Minimum confidence to keep
    iou_threshold=0.6,  # IoU threshold for removing overlaps
)

Examine the Results

1
2
print(f"Detected {len(crowns)} tree crowns")
crowns.head()

Visualize Results on Map

Display the detected tree crowns overlaid on the original image:

1
2
3
4
5
6
7
8
m = leafmap.Map()
m.add_raster(image_path, layer_name="Tree Image")
m.add_vector(
    output_path,
    layer_name="Tree Crowns",
    style={"color": "yellow", "fillColor": "yellow", "fillOpacity": 0.3, "weight": 2},
)
m

Using a Custom Model

If you have trained your own model, you can use it instead of the pre-trained models:

1
2
3
4
5
# Initialize with a custom model
# delineator = TreeCrownDelineator(
#     model_path="path/to/your/model.pth",
#     confidence_threshold=0.5,
# )

Tiling Orthomosaics

For large orthomosaics, you may want to tile them first before running predictions:

1
2
3
4
5
6
7
8
9
# Tile an orthomosaic for prediction
# tiles_dir = tile_orthomosaic(
#     image_path="path/to/orthomosaic.tif",
#     output_dir="./tiles",
#     tile_width=40,
#     tile_height=40,
#     buffer=30,
#     mode="rgb",  # Use 'ms' for multispectral imagery
# )

Preparing Training Data

If you want to train a custom model, you'll need to prepare your training data with manually delineated crown polygons:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Prepare training and test data
# train_dir, test_dir = prepare_training_data(
#     image_path="path/to/orthomosaic.tif",
#     crowns_path="path/to/manual_crowns.gpkg",
#     output_dir="./training_data",
#     tile_width=40,
#     tile_height=40,
#     buffer=30,
#     threshold=0.6,  # Minimum crown coverage per tile
#     test_fraction=0.15,  # Fraction for testing
# )

Stitching Predictions

After running predictions on tiles, you can stitch them together:

1
2
3
4
5
6
7
8
# Stitch tile predictions into a single crown map
# crowns = stitch_predictions(
#     geo_predictions_dir="./predictions_geo",
#     output_path="final_crowns.gpkg",
#     iou_threshold=0.6,
#     min_confidence=0.5,
#     simplify_tolerance=0.3,
# )

Tips for Best Results

  1. Image Resolution: detectree2 works best with high-resolution imagery (10cm or better).

  2. Tile Size: The default tile size of 40x40 meters works well for most applications. Adjust based on your tree sizes.

  3. Buffer Size: A buffer of 30 meters helps handle trees at tile edges.

  4. Confidence Threshold: Start with 0.5 and adjust based on your precision/recall needs.

  5. Training Data: If training custom models, ensure your manual crowns are:

  6. Densely clustered (not scattered)
  7. Comprehensively labeled (no missing trees in labeled areas)
  8. Accurately delineated

  9. GPU: For faster predictions, use a CUDA-enabled GPU.

References