A pipeline to process LiDAR point clouds from aerial campaigns into Digital Elevation Models (DEMs). Currently DSM, DTM and CHM generation are supported.
The code is structured around three main steps in the pipeline:
- Preprocessing (
preprocessing.py) – Assigns point clouds to target areas and filters outliers. - Processing (
processing.py) – Converts preprocessed point clouds into DSM, DEM, and CHM outputs. - Validation (
validation.py) – Evaluates generated models against other rasters or point data.
These steps are orchestrated by main.py and rely on helper methods in the /core directory.
Configuration settings are stored in /config/ and are initialized in main.py.
project_root/
├── 01_target_areas/ # Vector footprints of target AOIs (e.g. shapefiles or GeoJSON)
├── 02_pointclouds/ # Raw LiDAR point clouds (*.las or *.laz)
├── 03_las_footprints/ # Flight path footprints (generated if missing)
├── 04_preprocessed/ # Cleaned point clouds after outlier removal
├── 05_results/ # Output rasters from processing
│ └── <run_name>/
│ ├── DSM/ # Digital Surface Models
│ ├── DTM/ # Digital Terrain Models
│ └── CHM/ # Canopy Height Models (DSM - DTM)
├── 06_validation/ # External raster or vector data used for validation
- Assigns LiDAR point clouds to user-defined target areas (e.g., aerial image footprints or AOIs).
- Target areas should be stored as individual files but can be converted if necessary.
- Outliers are removed using statistical outlier removal techniques.
- Converts the preprocessed point clouds into:
- Digital Surface Models (DSM)
- Digital Elevation Models (DEM)
- Canopy Height Models (CHM)
- Outputs are saved as GeoTIFFs.
- Evaluates the generated models.
- Compares against:
- Single points or entire raster datasets.
- User-defined pixel subsets or complete rasters.
- Evaluates ground, surface, and vegetation height.
For efficiency, point clouds are split into smaller chunks and processed in parallel.
For an easy setup we recommend pixi. After clonting the repo simply run:
pixi installOf course, you can also use the old way. The pipeline requires Python 3.8+ and the following dependencies:
pip install pdal laspy shapely geopandas rasterio numpy scipy tqdmor using Conda:
conda install -c conda-forge pdal laspy shapely geopandas rasterio numpy scipy tqdmBut the easiest way is to use Pixi, trust me!
Before running the pipeline, update the paths and parameters in config.py.
You can create separate config files for different datasets or use cases and select them in main.py.
To process LiDAR data from start to finish, simply run:
python main.pyThis executes all pipeline steps: Preprocessing → Processing → Validation.
To run specific steps:
- Convert
main.pyinto a Jupyter Notebook. - Or manually comment out the steps you don’t need.
We have inculded an interactive user Interface which allows you to configure your parameters, set your processing steps and products. To access it, in your terminal run:
pixi run LidarProcessingor, after activating your environment:
python LidarProcessing.pyYour output will look like this:
GPU Acceleration for faster processing.
HPC (High-Performance Computing) Support for large-scale datasets.


