lidRalignment enables automatic alignment of forest plot-scale point clouds from different sources, such as ALS with TLS or MLS, TLS with MLS, or ALS with ALS, within a unified pipeline.
The package is robust to large alignment differences (e.g., up to 180 degrees of misalignment), noise, and leaf-on/leaf-off conditions, and it is parameterless. A full description of the internal pipeline is available 📖 here.



You need the latest versions of lidR and lasR:
install.packages(c('lidR', 'lasR', 'lidRalignment'), repos = 'https://r-lidar.r-universe.dev')The alignment pipeline consists of four stages, progressing from raw to extra-fine:
A full description of the internal pipeline is available 📖 here.
[!IMPORTANT]
When aligning airborne data with ground-based data, the airborne point cloud should be used as the reference. The ground point cloud is the moving point cloud, because airborne data are usually > better georeferenced.When aligning ground-based data with ground-based data, it is recommended to use the better of the two point clouds as the reference, i.e., the one with less occlusion. Typically, the TLS point cloud is moved to align with the MLS reference, not the opposite.
library(lidR)
library(lidRalignment)
options(lidR.progress = FALSE)
fref = "als_file.las"
fmov = "mls_file.las"
# Setup the pipeline. It is important to tell the object
# what we are aligning in order to perform or not
# the last extra fine alignment
alignment = AlignmentScene$new(fref, fmov)
alignment$set_ref_is_ground_based(FALSE)
alignment$set_mov_is_ground_based(TRUE)
alignment$set_radius(20)
# Run the alignment pipeline
alignment$align()
# Visualize the different level of alignment
alignment$plot("raw")
alignment$plot("coarse")
alignment$plot("fine")
alignment$plot("extra", compare_to = "fine")
# Get the final transformation matrix to register the entire point cloud.
M = alignment$get_registration_matrix()
crs = sf::st_crs(readLASheader(fref))
ofile = transform_las(fmov, M, crs)
alignment = AlignmentScene$new(fref, fmov)
alignment$set_ref_is_ground_based(FALSE)
alignment$set_mov_is_ground_based(TRUE)
alignment$prepare()
alignment$plot("raw")
alignment$coarse_align()
alignment$plot("coarse")
alignment$fine_align()
alignment$plot("fine")
alignment$extra_fine_align()
alignment$plot("extra", compare_to = "fine")lidRalignment has been sponsored by the University of Sherbrooke
![]()
The development of the package was supported by data collected by Jonathan Boucher, Anne Cotton-Gagnon and Jean Marchal with method contribution by Bastien Vandendaele: Canadian Forest Service.
