LasBuildSeg — Building Footprint Extraction from Aerial LiDAR
LasBuildSeg extracts building footprints from airborne LiDAR point clouds.
v0.2.1 adds an adaptive pipeline. Instead of fixed thresholds, the package now estimates its key parameters directly from the data: the CSF cloth settings are derived from point density and terrain slope, and the building height / TRI thresholds are derived from a coarse nDHM. The result is a workflow that adapts to each tile with far less manual tuning. The classic threshold-based functions are still included and unchanged.
:white_check_mark: If you are using this package for scientific research, please cite the paper `Reproducible Extraction of Building Footprints from Airborne LiDAR Data
Installation
pip install LasBuildSeg
This installs all dependencies, including the ones used by the adaptive
pipeline (cloth-simulation-filter, alphashape, matplotlib). Nothing extra
is required to run the full example.
Note:
cloth-simulation-filter(theCSFmodule) ships as compiled wheels. Ifpipcannot find a wheel for your Python version/platform it will try to build from source, which needs a C++ toolchain. The adaptive functions that needCSFandalphashapeimport them lazily, so the rest of the library still works even if those two are unavailable on your platform.
Dependencies
| Library | Version | Used for |
|---|---|---|
| pyproj | 3.5.0 | CRS handling |
| NumPy | 1.23.5 | arrays |
| SciPy | 1.10.1 | interpolation / filtering |
| Rasterio | 1.3.4 | raster I/O |
| OpenCV-python | 4.7.0.72 | morphology / contours |
| laspy | 2.0.0 | LAS/LAZ reading |
| lazrs | 0.5.0 | LAZ backend |
| PROJ | 0.2.0 | projection data |
| Shapely | >= 1.8.4 | geometry |
| GeoPandas | >= 0.13.2 | vector I/O |
| cloth-simulation-filter | >= 1.1.0 | CSF-based DTM (CSF module) |
| alphashape | >= 1.3.1 | alpha-shape footprints |
| matplotlib | >= 3.5.0 | optional mask preview |
Functions
Classic workflow: generate_dsm, generate_dtm, generate_ndhm,
read_geotiff, to_8bit, threshold, morph_open, filter_contours,
filter_contoursntri, close, write_geotiff, DSM_transform,
building_footprints_to_geojson, calculate_average_height.
Adaptive additions (v0.2.1): laz_pre_analysis,
generate_dsm_last_returns, generate_dtm_with_csf_last_returns,
align_rasters, analyze_low_res_ndhm, fxaa_like_smoothing,
extract_building_footprints_with_alphashape, rasterize_geojson.
Adaptive pipeline usage
Put your .laz file (and, for scoring, a ground-truth .geojson) in the same
folder, then:
import os
import geopandas as gpd
import numpy as np
import rasterio
import LasBuildSeg as Lasb
# --- Inputs ---
input_laz = 'tile.laz'
epsg_code = 6457
intermethod = 'nearest'
# --- Manual params ---
kernel_size = 3
alpha = 0.4
min_size, max_size = 50, 5000000
squareness_threshold, width_threshold = 0.3, 3
# 1) Derive CSF params from the raw cloud (point density + terrain slope)
csf_params = Lasb.laz_pre_analysis(input_laz)
# 2) Base rasters: last-return DSM, CSF DTM, aligned, nDHM, reprojected DSM
Lasb.generate_dsm_last_returns(input_laz, epsg_code, intermethod)
Lasb.generate_dtm_with_csf_last_returns(input_laz, epsg_code, 'dsm.tif', csf_params, intermethod)
Lasb.align_rasters('dtm_csf.tif', 'dsm.tif', 'aligned_dtm.tif')
Lasb.generate_ndhm('aligned_dtm.tif', 'dsm.tif') # -> ndhmtemp.tif (+ ndhm.tif)
Lasb.DSM_transform('dsm.tif') # -> dsm3857.tif
# 3) Adaptive height / TRI thresholds from the coarse nDHM
adaptive = Lasb.analyze_low_res_ndhm('ndhmtemp.tif')
tri_threshold = adaptive['tri_threshold']
height_threshold = adaptive['height_threshold']
filter_height_threshold = height_threshold * 0.8
# 4) Alpha-shape footprints, then rasterize onto the EPSG:3857 grid
Lasb.extract_building_footprints_with_alphashape(
'ndhmtemp.tif', alpha, height_threshold, epsg_code, kernel_size)
Lasb.rasterize_geojson('alpha_shape_buildings.geojson', 'dsm3857.tif', 'alpha_shape_buildings.tif')
# 5) Refine contours (S1 = no TRI, S2 = with adaptive TRI)
mask, profile = Lasb.read_geotiff('alpha_shape_buildings.tif')
dem, _ = Lasb.read_geotiff('dsm3857.tif')
s1 = Lasb.filter_contoursntri(mask, profile, min_size, max_size,
squareness_threshold, width_threshold, filter_height_threshold)
s2 = Lasb.filter_contours(mask, dem, profile, min_size, max_size,
squareness_threshold, width_threshold, filter_height_threshold, tri_threshold)
# 6) Save results
Lasb.write_geotiff('buildings.tif', s2, profile)
Lasb.building_footprints_to_geojson('buildings.tif', 'buildings.geojson')
print('All steps are complete.')
A full, runnable version with output folders, average-height attachment and
IoU scoring is provided in TestLaz/TestSingleLaz.py in the source repository.
Classic (threshold-based) usage
The original workflow still works exactly as before:
import LasBuildSeg as lasb
lasb.generate_dsm(input_laz, epsg_code, intermethod)
lasb.generate_dtm(input_laz, epsg_code, intermethod, multy)
lasb.generate_ndhm('dtm.tif', 'dsm.tif')
img, profile = lasb.read_geotiff('ndhm.tif')
lasb.DSM_transform('dsm.tif')
dem, _ = lasb.read_geotiff('dsm3857.tif')
img_8bit = lasb.to_8bit(img)
img_thresh = lasb.threshold(img_8bit, block_size, constant)
img_open = lasb.morph_open(img_thresh, kernel_size)
building_mask = lasb.filter_contours(img_open, dem, profile, min_size, max_size,
squareness_threshold, width_threshold, height_threshold, tri_threshold)
building_mask_closed = lasb.close(building_mask, CloseKernel_size)
lasb.write_geotiff('buildings.tif', building_mask_closed, profile)
lasb.building_footprints_to_geojson('buildings.tif', 'building.geojson')
Data
The example uses a point cloud dataset provided by GISCUP 2022. If you don't have your own data, you can use this dataset. The test script also uses scoring functions adapted from GISCUP 2022's eval.py.
PROJ note
If your PROJ_LIB environment variable points to an older PROJ install you may
hit projection errors. Either unset it, point it at the PROJ shipped with pyproj
(find it via pyproj.datadir.get_data_dir()), or just run the script in a fresh
environment.
Metadata
Release files for LasBuildSeg 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| lasbuildseg-0.2.1.tar.gz | 24.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| lasbuildseg-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 46.3 kB
Release files / lasbuildseg-0.2.1.tar.gz
| Download URL | lasbuildseg-0.2.1.tar.gz |
|---|---|
| Size | 24.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4bccc2852b8c4f4f4b327bfcd61f5c9de889d9e8d7f05030e473135fd19770e7
|
|
BLAKE2b-256 checksum How to use checksums |
e9efd99e21991643ea94fb7705345c0dde54ad6bdeced27d66bcc26a77909e83
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.9
|
Release files / lasbuildseg-0.2.1-py3-none-any.whl
| Download URL | lasbuildseg-0.2.1-py3-none-any.whl |
|---|---|
| Size | 21.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b2dbc440126c3c2d1250730416fe279371877945aded8796a2ed0f1ccf50759c
|
|
BLAKE2b-256 checksum How to use checksums |
0a16c88f3340e0cc68d31158e8abf60cc7469568d03236c48dc50987640235ed
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.9
|