After annotating individual trees or plot polygons in QGIS, the most common next step is to get a height for each one. This script extracts that directly from DSM and DTM rasters without needing to process the original point cloud.
What it does
The tree_heights_from_dsm_dtm.py script adds a height field (DSM − DTM in metres) to every feature in the active vector layer.
The sampling approach depends on geometry type:
- Point features — samples the exact DSM and DTM raster values at the point’s location
- Polygon features — takes the maximum DSM value minus the minimum DTM value within the polygon’s bounding box (approximates the tallest point inside the polygon)
If the vector layer and rasters are in different CRS, the script reprojects the vector automatically before sampling.
Output: {input_name}_with_height.geojson saved alongside the original, with a new height field, loaded into the QGIS project.
What you need
- QGIS 3.28 or newer
numpy,rasterio(bundled with QGIS)- Active point or polygon layer (tree annotations or plot polygons)
- DSM raster with “_dsm” in the layer name, checked in the Layers panel
- DTM raster with “_dtm” in the layer name, checked in the Layers panel
- The
tree_heights_from_dsm_dtm.pyscript from the Vegetation & Field Analysis Pack
Steps
- Load your DSM and DTM rasters into QGIS. Layer names must contain
_dsmand_dtm. - Load your tree point or polygon layer and click it to make it the active layer.
- Check (tick) the DSM and DTM rasters in the Layers panel.
- Open Plugins → Python Console → Show Editor.
- Paste the script and click Run.
The output file is saved alongside the source vector file and added to the QGIS project.
Accuracy notes
- Point layers — height accuracy depends on the DSM/DTM spatial resolution. At 5 cm/pixel a single point is sampled; at 20 cm/pixel nearby objects can affect the reading.
- Polygon layers — the script uses max DSM − min DTM within the bounding box. For precise crown height measurement, use point features at the estimated tree top location.
Downstream use
Once you have height values on each feature, you can:
- Run
plot_tree_attributes_histograms.pyto compare height distributions bytree_type - Export the GeoJSON for analysis in Python or R
- Classify by height using
classify_layer.py
Get the script
tree_heights_from_dsm_dtm.py is part of the Vegetation & Field Analysis Pack — six vegetation analysis scripts for QGIS at $40 USD.