Skip to content
← Home

Geospatial · Remote Sensing · 2026

Denver Urban Tree Classification: Mapping a Neighborhood's Canopy from Free Imagery

I mapped 18,272 tree crowns in Denver's Hale neighborhood from public aerial imagery, a five-date Sentinel-2 series, and airborne LiDAR. The model sorts each crown into one of five forestry management classes. It supports screening and field prioritization; it does not replace an arborist survey.

The project began in an AMS course taught with NASA and CIRA, then expanded into crown segmentation, spatial validation, and model comparisons.

Tom Shanks

HALE / DENVER CANOPY STRATA
Scroll-controlled view selected
Ash (EAB risk)Elm (DED risk)ConiferMapleOther deciduous
  1. 0–<6 m2,96916.2% of records

    Other deciduous: 2,655 · conifer: 231

    Class counts
    Ash (EAB risk)
    19
    Elm (DED risk)
    7
    Conifer
    231
    Maple
    57
    Other deciduous
    2,655
  2. 6–<12 m6,52035.7% of records

    Other deciduous: 4,614 · conifer: 743

    Class counts
    Ash (EAB risk)
    659
    Elm (DED risk)
    35
    Conifer
    743
    Maple
    469
    Other deciduous
    4,614
  3. 12–<18 m5,80931.8% of records

    Other deciduous: 3,299 · conifer: 858 · ash: 841

    Class counts
    Ash (EAB risk)
    841
    Elm (DED risk)
    125
    Conifer
    858
    Maple
    686
    Other deciduous
    3,299
  4. 18 m+2,97416.3% of records

    Other deciduous: 1,023 · elm: 995

    Class counts
    Ash (EAB risk)
    106
    Elm (DED risk)
    995
    Conifer
    525
    Maple
    325
    Other deciduous
    1,023

18,272 exported crown records · height is each crown’s maximum in the LiDAR-derived canopy-height model. Classes are model predictions. Bands use unrounded heights; 12 zero-height records remain in 0–6 m.

Counts, method & source hashes ↗

18,272 predicted crowns, sized by canopy area. Scroll to separate LiDAR height bands; drag to rotate. Orange marks likely ash for field screening, not confirmed species or infestation. Component, packer and the 180 KB crown field are public: spatial-fields/canopy-strata

Overall accuracy
69.0%
Spatially validated
~66%
Over pixel baseline
+30.7 pts
Crowns mapped
18,272

Why species is the wrong target

A pixel classifier across ten common species reached about 17% accuracy. NAIP provides four bands, and many species look alike at that scale. Whole crowns recover more signal, but species labels remain too uncertain to replace field identification.

I regrouped the labels into ash, elm, maple, conifer, and other deciduous: categories tied to disease risk, water demand, and field treatment.

Five Sentinel-2 dates add seasonal behavior. Conifers stay green into November while deciduous crowns leaf out and fade, giving the classifier information a single summer image cannot provide.

Line chart of average Sentinel-2 greenness for each management class across five 2025 dates.
Average Sentinel-2 greenness for each class through the 2025 season. The conifer line stays high into the autumn while the deciduous classes rise and fall, and that seasonal shape helps tell them apart.

Building the map

A vegetation-masked watershed splits the DRCOG LiDAR canopy-height raster into 18,272 crowns. Each crown stays one object through feature extraction and classification.

Each crown has 109 features from NAIP color and near-infrared, Sentinel-2 seasonality and vegetation indices, plus LiDAR height and shape. Matching crowns to Denver's arborist inventory produced 3,764 labels. Gradient boosting won a four-model comparison.

Pipeline diagram from imagery and LiDAR to crowns to features to classifier to map.
The pipeline, end to end: align the rasters, build the LiDAR height model, segment the canopy into crowns, measure features per crown, then classify. It runs from a single script with free data.

A look without labels

Unsupervised clustering shows structure in greenness and height, along with the main ambiguity: maple overlaps heavily with other deciduous crowns. The supervised model makes most of its errors there.

Two scatter plots of crowns by greenness and height: clusters found without labels, and the true classes.
Each crown placed by greenness and height. On the left, groups a clustering algorithm finds with no labels. On the right, the true classes, where maple and other deciduous overlap heavily.

Results

Overall accuracy is 69.0%, up from 38.3% for the pixel baseline. Balanced accuracy is 62.8%. Conifer and ash perform best; maple remains weakest because it overlaps other deciduous crowns.

Management classPrecisionRecallF1Crowns
Ash (Emerald Ash Borer risk)0.710.630.66204
Conifer (drought tolerant)0.840.710.77120
Elm (Dutch Elm Disease risk)0.770.570.65118
Maple (water demanding)0.690.390.50180
Other deciduous0.650.850.74508
Confusion matrix for the five management classes.
Where the model confuses classes. Most errors are maple and the risk classes being read as the large other-deciduous group.
Bar chart of feature importance by source.
Which inputs the model relies on. Color and season dominate; the LiDAR height adds about a tenth.

NAIP color and Sentinel-2 seasonality account for nearly nine tenths of feature importance; LiDAR height contributes about a tenth. Most separation comes from how crowns reflect light across bands and seasons.

Bar chart comparing the pixel baseline and the crown model accuracy.
The earlier pixel-based version reached 38.3 percent on the same five classes. Working with whole crowns and the fuller feature set raised that to 69.0 percent.

Spatial validation

Random splits can flatter spatial models because nearby crowns share lighting and planting patterns. I therefore withheld complete 200 m and 400 m blocks during testing.

Accuracy holds at 66.4% for both block sizes, about two points below the random split. That supports use within Hale; it does not establish transfer to another neighborhood.

EvaluationOverall accuracyBalanced accuracy
Random split, same model0.6850.623
Spatial blocks, 200 m0.6640.597
Spatial blocks, 400 m0.6640.597
Bar chart comparing random and spatial-block cross-validation accuracy.
Random versus spatial-block validation on the same model. Holding out whole blocks lowers the score by about two points.
Crowns colored by spatial cross-validation fold.
Crowns grouped into spatial folds, so whole blocks of the neighborhood are tested together rather than split apart.

How far species can go

Crown-level classification across 21 sufficiently labeled species reached about 54% accuracy, compared with 17% for the pixel baseline. Blue spruce, American elm, honeylocust, and ash separate best; lindens, oaks, and ornamental maples often merge with similar broadleaf species.

That is useful for exploration, but not reliable enough for field identification. The five management classes remain the operational output.


From map to action

The model flags about 1,600 crowns as likely ash for field confirmation and treatment planning. Adding an October image improved ash recall by about seven points, making seasonal timing the most useful tested change for Emerald Ash Borer screening.

Aerial map of the neighborhood with predicted ash crowns highlighted in orange.
Predicted ash crowns across the neighborhood, the trees most exposed to the Emerald Ash Borer. A screening layer to prioritize inspection, drawn over the aerial image.

Canopy change, 2016–2025

For change analysis I used NASA's Harmonized Landsat-Sentinel surface reflectance, which places both sensors on a common 30 m grid.

Cloud-free summer composites show a broadly stable neighborhood: about 2% vegetation loss and 2.5% gain. Small differences can also come from acquisition date and sun angle, so I do not interpret each changed pixel as a tree-level event.

A 30 m HLS pixel covers several trees and surrounding ground. It measures neighborhood change, while the one-meter workflow maps individual crowns.

Four panels: NDVI greenness for Hale in 2016 and 2025, their difference, and a canopy change map.
Harmonized Landsat-Sentinel surface reflectance over Hale, 2016 and 2025: greenness each year, the change between them, and the resulting canopy classes. The neighborhood reads as broadly stable, with small areas of loss and gain that roughly balance.

Coarse-scale foundation model

I ran NASA and IBM's Prithvi-EO model over six-band HLS imagery for central Denver, then clustered its learned features without labels. The published weights ran locally.

At roughly 480 m per patch, Prithvi separates broad land-cover patterns but misses tree-level variation. It is a useful coarse baseline, not a substitute for the one-meter crown workflow.

Left, an HLS true-color image of central Denver with Hale outlined. Right, Prithvi's learned features grouped into land-cover clusters without labels.
Prithvi-EO, a NASA and IBM geospatial foundation model, run over a 6.7 km HLS image of central Denver with Hale outlined. Left, the true-color image. Right, the model's own learned features grouped without any labels. At its 480 meter patch scale the neighborhood reads as a largely uniform residential canopy, a reminder that single-tree detail still needs the 1 meter crown model.

Crown-scale learned models

DINOv2 embeddings from one RGB aerial chip per crown reached 32.9% accuracy, well below the engineered feature model.

A purpose-built network combines RGB, near-infrared, LiDAR height, and the Sentinel-2 time series. It matches the engineered model on balanced accuracy and raises elm recall from 0.57 to 0.82 and maple from 0.39 to 0.55, while lowering overall accuracy.

With 3,764 labels, gradient boosting still leads overall. The multimodal network performs better on rare classes; the RGB-only foundation model lacks the spectral, seasonal, and height inputs the task needs.

Crown-scale modelOverall accuracyBalanced accuracy
Engineered features + gradient boosting0.6900.628
Multimodal deep net (full data, local GPU)0.5690.632
DINOv2 foundation model (RGB only)0.3290.360
Grouped bar chart of per-class recall for the engineered model, the multimodal deep net, and DINOv2, all run locally on an RTX 3060.
Recall by management class for the three crown-scale models, all run locally on an RTX 3060. The multimodal net (blue), which sees the full multispectral, seasonal and height data, beats the engineered model (green) on the hard elm and maple classes and ties it on balanced accuracy, while the RGB-only foundation model (gray) trails throughout.

Data and tools

Every input is free and openly licensed. One script runs the pipeline. The crown-based method adapts Cross (2019) from WorldView-3 tropical forest imagery to public Denver data and urban-forestry classes.

DatasetSourceLicense
NAIP 2023 aerial imagery (4 band, 30 cm)USDA NRCS, via AWSPublic domain
Denver tree inventory (arborist survey)Denver Open Data PortalCC BY
Canopy height modelDRCOG 2020 3DEP airborne LiDARPublic domain
Sentinel-2 surface reflectance, 5 datesESA CopernicusFree, open
HLS surface reflectance (L30/S30, 30 m)NASA LP DAAC, via EarthdataFree, open

Built with Python, Rasterio, GeoPandas, scikit-image, scikit-learn and XGBoost, with QGIS for inspection. Everything ran on one desktop machine: the feature pipeline on the CPU, the neural networks on a single RTX 3060. The pretrained models it draws on were downloaded and run there too. Study area: the Hale neighborhood, about 4.6 square kilometers.

Source available on request.