A complete workflow for estimating forest tree height from LiDAR point clouds or multi-source remote sensing imagery using QGIS and Python.
Import Sentinel-2 imagery, Landsat imagery, DEM or LiDAR/CHM data, and check coordinate systems, resolution and valid extent.
Make sure all data share the same coordinate system; the UTM projection for your study area is recommended.
Apply the necessary atmospheric correction, geometric correction, clipping and cloud masking to Sentinel-1/2 or Landsat data.
Sentinel-2 Level-2A products are already atmospherically corrected, so focus on cloud masking and clipping to the study area.
Extract variables such as NDVI, EVI, texture features, DEM, slope and aspect, and build a feature matrix at sample-point or pixel level.
rasterio, geopandas and rasterstats can batch-extract raster values for sample points.
Use CHM or field-measured tree height as labels and train and validate random forest, XGBoost or linear models.
Report at least R², RMSE and MAE, and keep training and validation results separate.
Export the tree height predictions as GeoTIFF and produce thematic maps and check results in QGIS.
Remove outliers and invalid areas, and avoid mistaking areas without CHM coverage for low tree height.