Processing LiDAR Point Clouds: Extracting Canopy Height Models (CHM) in QGIS & CloudCompare
1. Processing LiDAR Point Clouds: Extracting Canopy Height Models (CHM) in QGIS & CloudCompare: Introduction
Light Detection and Ranging (LiDAR) is a remote sensing technology that uses laser pulses to measure distances between a sensor and objects on the Earth’s surface. Airborne LiDAR systems can capture thousands or millions of three-dimensional points, recording the terrain, forest canopy, buildings, and other features.
Unlike conventional satellite imagery, which primarily records reflected electromagnetic energy, LiDAR provides direct three-dimensional measurements of the surveyed environment. This makes it particularly valuable for forestry inventories, terrain modelling, vegetation analysis, and urban infrastructure mapping.
However, raw LiDAR data is not immediately suitable for many GIS analyses. Before estimating vegetation height, analysts must inspect the point cloud, identify ground returns, and generate elevation rasters representing both the terrain and the upper surface.
This tutorial demonstrates how to process LiDAR point clouds to create a Canopy Height Model (CHM) using CloudCompare and QGIS. The workflow uses CloudCompare for point-cloud inspection, cleaning, ground classification, and rasterization, followed by QGIS for raster alignment, mathematical subtraction, and visualization.
QGIS supports LAS and LAZ point clouds, while CloudCompare provides specialized tools for manipulating point clouds and separating ground from non-ground measurements.
Software and input data
| Requirement | Purpose |
|---|---|
| CloudCompare | Inspect, clean, and classify LiDAR points |
| QGIS | Align elevation rasters, calculate CHM, and create maps |
Input .las or .laz |
Original LiDAR point cloud |
| Output GeoTIFFs | Ground DEM/DTM, DSM, and final CHM |
Expected outputs:
-
ground_points.las— points classified as ground by the workflow. -
dem_ground.tif— bare-earth elevation model. -
dsm_surface.tif— upper surface elevation model. -
chm_final.tif— estimated canopy height above the ground.
Recommended starting resolution: 1 metre for a sufficiently dense airborne LiDAR dataset. Choose a coarser resolution when point density is low; resolution must reflect the survey’s sampling density and the detail required.
2. Core Concepts: DSM vs. DEM vs. CHM
Before processing the data, it is important to understand what each elevation model represents.
Digital Surface Model (DSM)
A DSM represents the upper surface of the landscape, including trees, rooftops, and other objects. It can be generated by selecting first returns or by taking the maximum observed elevation within each raster cell.
Output: dsm_surface.tif
Digital Elevation Model (DEM) / Digital Terrain Model (DTM)
A bare-earth DEM represents the ground surface after vegetation and other elevated objects have been excluded. In this workflow, ground-classified LiDAR points are used to estimate the terrain.
Output: dem_ground.tif
Canopy Height Model (CHM)
A CHM expresses the elevation of the upper surface relative to the underlying ground. Subtracting the bare-earth elevation from the surface elevation removes the terrain’s vertical contribution.
Output: chm_final.tif
The core mathematical relationship is:
For example, if a DSM cell has an elevation of 128.4 metres and its corresponding DEM cell has an elevation of 116.7 metres:
The estimated canopy or upper-object height at that location is therefore 11.7 metres.
Important distinction: The CHM represents height above the modelled ground, not necessarily the exact height of an individual tree. Buildings and other elevated objects can also appear in the CHM unless they are identified and removed.
3. Step-by-Step LiDAR Processing Workflow
Step 1: Inspect and clean the raw LAS/LAZ point cloud in CloudCompare
The first stage is to inspect the input point cloud and identify obvious data-quality problems.
CloudCompare can open common LiDAR formats, including .las and .laz. LAS stores point-cloud records in a standard format, while LAZ provides a compressed representation.
Procedure
-
Launch CloudCompare.
-
Select File → Open and load the
.lasor.lazfile. -
If CloudCompare requests a global shift because coordinates are large, accept the suggested shift when appropriate. This helps maintain numerical precision when working with projected coordinates.
-
Select the point cloud in the database tree.
-
Inspect the cloud in the 3D viewport. Rotate the scene and examine its vertical structure.
-
Open the cloud’s properties or scalar-field list to inspect available attributes such as elevation, intensity, classification, and return number.
-
Check the coordinate reference system and horizontal and vertical units. If the CRS is missing or uncertain, verify it against the survey metadata rather than guessing.
Cleaning noise and outliers
Look for isolated points far above the canopy, below the terrain, or outside the main survey area. These may be noise or erroneous measurements.
Depending on your CloudCompare build, use its statistical outlier removal tools or crop the cloud to the study area. Apply filtering conservatively: an unusually high point might be a genuine treetop rather than noise.
Save the original point cloud separately before cleaning. This preserves a reference copy if later processing removes valid measurements.
Suggested figure: CloudCompare showing an airborne LiDAR forest point cloud, with the ground surface and tree canopy visible in the 3D viewport.
Step 2: Classify ground and non-ground points using the CSF filter
The DEM must represent the bare-earth surface. If vegetation or rooftops are included in the ground model, the resulting canopy heights will be underestimated or otherwise distorted.
The Cloth Simulation Filter (CSF) is a ground-filtering method that models a simulated cloth over an inverted representation of the terrain. It uses the resulting surface to distinguish ground returns from points above the ground.
Procedure
-
Select the input point cloud in CloudCompare.
-
Open Plugins → CSF or the corresponding CSF filter command in your installed build.
-
Choose the terrain type:
-
Flat: relatively level terrain.
-
Relief: rolling or undulating terrain.
-
Steep slope: steep or mountainous terrain.
-
-
Review the advanced settings.
-
Set the cloth resolution and classification threshold according to the terrain and point density.
-
Start with a classification threshold around
0.5in the dataset’s vertical units when appropriate, then test and adjust it. This is a starting point, not a universal optimum. -
For steep terrain, consider enabling slope post-processing.
-
Run the filter and inspect the resulting ground and off-ground subsets.
-
Save the extracted point clouds as separate LAS/LAZ files if required for your next processing stage.
A cloth resolution of approximately 0.5–1 metre can be a reasonable initial test for some dense datasets, but the appropriate value depends on terrain complexity, vegetation density, and the scale of the features you need to retain.
Validate the classification before continuing.
The ground subset should follow the terrain beneath the canopy rather than tracing treetops or building roofs. Incorrectly classified low vegetation can introduce bumps into the DEM, while incorrectly excluded ground points can leave holes.
Also note that the CloudCompare CSF workflow typically produces separate ground and off-ground point clouds. Do not assume that it has written LAS classification code 2 into every ground point unless you have verified the saved file.
Suggested figure: CloudCompare displaying ground points and off-ground vegetation points in contrasting colours after CSF classification.
Step 3: Rasterize the ground points to create a bare-earth DEM
Once the ground subset has been checked, convert its 3D elevations into a continuous raster surface.
CloudCompare’s Rasterize tool converts point clouds to a 2.5D grid and can export the result as a GeoTIFF raster. It supports minimum, average, and maximum height statistics, as well as interpolation of empty cells.
Procedure
-
Select the extracted ground-point cloud in CloudCompare.
-
Open Tools → Projection → Rasterize.
-
Set the projection direction to Z.
-
Set the grid step to your target pixel size, such as
1.0for a 1-metre raster when supported by the survey density. -
Choose average height to reduce the influence of minor point-level variation within each cell. Inspect the results and consider alternative interpolation methods if terrain characteristics require them.
-
Click Update Grid to generate the raster preview.
-
Review empty cells. Interpolate small gaps when appropriate, but do not automatically fill large data voids with a constant elevation or unrestricted interpolation.
-
Export the grid using Raster (GeoTIFF).
-
Save the result as
dem_ground.tif.
Why use average height?
Ground returns can vary slightly within a cell because of measurement noise and natural surface variation. Averaging accepted ground points can provide a stable estimate of local terrain elevation. In steep or highly variable terrain, however, you should inspect whether this generalization adequately represents the underlying surface.
Critical grid setting: Record the raster grid’s origin, extent, and cell size. Ideally, the DEM and DSM should use the same grid. CloudCompare’s Edit Grid controls can be used to define the grid position. When necessary, the rasters can be aligned later in QGIS.
Suggested figure: CloudCompare Rasterize dialog configured to generate a ground elevation GeoTIFF.
Step 4: Rasterize the upper surface to create a DSM
Next, create a Digital Surface Model representing the highest observed surface within each raster cell.
For this step, use the cleaned original point cloud, not just the off-ground subset. The original cloud retains ground points in open areas and beneath gaps in the canopy, allowing the DSM to represent the uppermost observed surface across both vegetated and open locations.
Procedure
-
Select the cleaned, complete point cloud in CloudCompare.
-
Open Tools → Projection → Rasterize.
-
Set the projection direction to Z.
-
Use the same cell size as the DEM.
-
Select maximum height as the cell statistic.
-
If the LAS/LAZ data contain reliable return-number attributes, you may optionally filter to first returns for a first-return surface. Otherwise, taking the maximum Z value within each cell is a straightforward way to estimate the upper surface.
-
Click Update Grid.
-
Confirm that the cell size and raster grid alignment match those specified for the DEM.
-
Export the raster as a GeoTIFF named
dsm_surface.tif.
The maximum-height operation can be represented as:
Here, \(C_{x,y}\) is a raster cell and \(Z_i\) represents the elevations of points falling within it.
Why not use only the non-ground cloud?
Using only non-ground points can leave gaps where the cloud contains no above-ground return. Including the full cleaned cloud produces a more complete surface representation, although gaps in acquisition coverage and other data-quality limitations may still require attention.
Inspect the DSM for isolated high spikes caused by residual noise. Such outliers can generate artificial peaks in the CHM.
Suggested figure: A DSM raster showing the upper surface of a forest, including treetops and open-ground areas.
Step 5: Align the DSM and DEM in QGIS
Before subtraction, verify that the two rasters share the same coordinate reference system, units, pixel size, grid alignment, and spatial coverage.
Although both rasters may have a nominal 1-metre cell size, they can still be misaligned if their grid origins differ. Pixel-by-pixel subtraction between differently aligned surfaces can introduce artificial height differences.
Procedure
-
Open QGIS and create a new project.
-
Add
dem_ground.tifanddsm_surface.tif. -
Inspect each raster’s properties to confirm the CRS, pixel size, extent, and NoData settings.
-
If the grids already match, proceed directly to the next step.
-
If alignment is required, open the Processing Toolbox and search for Align rasters under the Raster tools group.
-
Configure the DSM as the reference grid.
-
Align the DEM to the DSM’s resolution, CRS, and grid alignment. Use a suitable interpolation method, such as bilinear resampling for continuous elevation data, when resampling is necessary.
-
Save the aligned output as
dem_aligned.tif.
QGIS provides raster-alignment tools for resampling raster layers to a reference cell size and CRS.
Do not replace NoData cells with zero indiscriminately. A missing ground elevation is not the same as ground elevation zero metres, and treating it as zero would create misleading canopy heights.
Step 6: Calculate the Canopy Height Model using the QGIS Raster Calculator
This is the central calculation in the workflow.
The DSM represents the upper surface elevation, while the DEM represents the underlying ground elevation. Subtracting the second from the first isolates their vertical difference.
Procedure
-
Open Raster → Raster Calculator in QGIS.
-
Select the raster bands for the DSM and aligned DEM.
-
Enter the following expression, substituting your actual layer names if necessary:
"DSM@1" - "DEM@1"
In this expression, DSM@1 represents band 1 of the DSM layer, and DEM@1 represents band 1 of the aligned DEM layer.
-
Set the output extent and resolution to match the desired analysis grid.
-
Choose a GeoTIFF output file named
chm_final.tif. -
Run the calculation.
The result is:
For example:
| Raster | Elevation |
|---|---|
| DSM | 128.4 m |
| DEM | 116.7 m |
| CHM | 11.7 m |
The resulting raster stores height estimates rather than absolute elevations, provided the input vertical units and datums are compatible.
Interpreting negative values
A correctly aligned surface model will generally produce non-negative height estimates in valid cells. Small negative values can arise from classification errors, interpolation differences, or residual misalignment.
Do not simply clip every negative value to zero before investigating the cause. Review the surfaces first. If the remaining negative values are demonstrably minor artefacts, you can create a cleaned CHM in which those values are set to zero or NoData, depending on your analysis requirements.
Large negative values or implausibly tall peaks usually indicate a problem that should be resolved before publication.
Step 7: Style and validate the final CHM
A valid CHM should show meaningful variation in vegetation height, rather than simply reproducing the underlying terrain or displaying random spikes.
Procedure
-
Right-click
chm_final.tifand open Properties → Symbology. -
Choose Singleband pseudocolor.
-
Select a continuous colour ramp, such as Viridis, or a vegetation-oriented ramp from shorter to taller canopy.
-
Set an appropriate display range. For an initial inspection, a range of
0–30 mmay work for some forest types; adjust it to the actual dataset. -
Use the QGIS Identify tool to inspect pixels in several locations.
-
Compare open-ground areas, individual trees, dense forest, and any known structures against the original point cloud and elevation rasters.
-
Review the raster statistics and histogram for unexpected negative values, isolated high peaks, or widespread NoData gaps.
A useful quality-control checklist is:
-
Open areas should generally have CHM values near zero.
-
Tree crowns should appear as elevated features.
-
Ground undulations should not dominate the CHM.
-
Obvious buildings and other non-vegetation features should be identified if the objective is a forest-only canopy model.
-
NoData areas should be understood rather than silently treated as zero-height canopy.
The final product, chm_final.tif, is now ready for further forestry analysis, subject to validation against suitable reference data.
4. Common Problems and Troubleshooting
| Problem | Likely cause | Recommended solution |
|---|---|---|
| Negative CHM values | Misalignment, classification errors, or interpolation differences | Check the grid alignment and inspect DSM/DEM values before correcting |
| Unrealistically tall trees | High noise points or incorrect DSM maximums | Reinspect outliers and compare against the point cloud |
| Holes in the CHM | Missing returns or NoData in the DEM/DSM | Inspect data coverage and use justified interpolation where appropriate |
| DEM includes trees | Incorrect ground classification | Adjust CSF parameters and inspect the ground subset |
| Building footprints appear as tall canopy | DSM includes buildings | Mask building footprints or use validated vegetation-only data |
| Different-looking raster extents | DEM and DSM use different grids | Align the rasters before calculation |
5. Applications in Forestry and Biomass Estimation
A Canopy Height Model is a useful input to forest structure and inventory workflows because it describes the relative height of the upper vegetation surface.
Forest inventory and tree-height estimation: Local CHM maxima can help identify potential tree tops. With appropriate filtering and segmentation, analysts can estimate individual-tree heights and crown dimensions. These are estimates, and dense, overlapping, or multi-layered canopies can make individual-tree delineation difficult.
Canopy cover and forest structure: Applying height thresholds can help estimate the proportion of an area occupied by vegetation above a specified height. CHM statistics can also describe variation in canopy height across forest stands.
Biomass estimation: Mean height, height percentiles, canopy cover, and other CHM-derived metrics can serve as predictors in calibrated biomass models. However, canopy height alone is not a direct measurement of biomass. Reliable biomass estimation generally requires suitable field-plot data and models that may incorporate diameter at breast height (DBH), species, wood density, and tree allometry.
Habitat and ecological assessment: Canopy height patterns can help characterize vertical structure and identify differences between vegetation types or forest conditions.
For all these applications, validate the model’s accuracy against independent measurements or field observations whenever possible.
6. Summary
The workflow combines CloudCompare’s point-cloud processing tools with QGIS raster analysis to produce a Canopy Height Model:
-
Inspect and clean the raw LAS/LAZ data.
-
Separate ground and non-ground points with the CSF filter.
-
Rasterize ground returns to generate a bare-earth DEM.
-
Rasterize the cleaned full cloud using maximum Z values to generate a DSM.
-
Align the elevation rasters and calculate
CHM = DSM − DEMin QGIS. -
Inspect, style, and validate the resulting CHM before applying it to forestry analysis.
The most important quality-control decisions are the accuracy of ground classification, the treatment of empty cells, and the alignment of the DSM and DEM. A well-constructed CHM provides a valuable foundation for forest inventory, canopy characterization, and biomass modelling.