Lite3DRegLib, with Python and C++ APIs, is a lightweight 3D point cloud and mesh registration library supporting both rigid and non-rigid alignment. It is designed for research and educational purposes, while also serving as a solid foundation for developing advanced 3D applications. Compared to existing geometry and registration libraries (such as PCL ,Open3D), Lite3DRegLib is designed to be lightweight while using modern, high-performance, and robust registration algorithms, enabling fast and reliable 3D point cloud and mesh alignment.Designed to be accessible for beginners or users who only need registration results, Lite3DRegLib also includes interactive visualization and user-friendly tools via Gradio, making it easier to explore, analyze, and experiment with 3D data.
-
Lightweight:The source code is less than 0.3 MB.
-
Efficient and Robust:By leveraging our algorithms, Lite3DRegLib significantly outperforms traditional registration methods such as ICP and CPD in terms of speed and robustness.Rigid registration algorithm:Fast-Robust-ICP;NonRigid registration algorithm:spare.
-
Easy and Flexible:Lite3DRegLib provides an interactive interface through Gradio, making it easy for users to visualize 3D registration results in real time. Users can conveniently adjust parameters and settings to explore different configurations, experiment with example datasets, and fine-tune the alignment process, all without writing additional code.
|
|
|
|
|
|
Interactive Interface:
You can adjust the registration parameters using the dropdown menus, and click the Reset to Default Parameters button to revert all settings to their default values.
The repository includes a CMakeLists.txt file in its root directory, which serves as the main entry point for configuring and building programs, along with several subfolders.
- 3rd_party – source code of third-party libraries
- cmake – CMake-related configuration files
- cpp – source code of Lite3DReg
- examples – example data, C++ example, Python example
- python – Python bindings for Lite3DReg
- app.py – a Python visualization with Gradio
- apt.txt – a list of required system packages
- requirements.txt – a list of required Python dependencies
- Eigen-3.4.0
- OpenMesh-8.1
- (Optional for Linux) MKL. It is used to speed up the LDLT solver(https://eigen.tuxfamily.org/dox-devel/group__PardisoSupport__Module.html). If it is not installed, Eigen's SimplicialLDLT will be used instead.
To install the required Python dependencies, use the following command:
pip install numpy gradio plyfile trimesh plotly
Run cd scripts && ./compile.sh and a library and an executable Lightweight3DRegDemo.exe of examples will be generated in the build/examples folder.
Or you can open CMakeLists.txt in Qtcreator, select the Release build mode, and compile.
RigidFricpRegistration *rigid;
NonrigidSpareRegistration *spare;
// Directly read data from files and output registration results
rigid->Reg(target_file, source_file, outpath);
spare->Reg(target_file, source_file, outpath);
// Adjust parameters
rigid->Paras_init(use_init=false, file_init="", max_iter=80, stop=1e-5);
spare->Paras_init(int iters = 30 ,double stopcoarse=1e-3,double stopfine=1e-4,bool uselandmark = false,std::vector<int> src=std::vector<int>(),std::vector<int> tar=std::vector<int>());
// Reset to default parameters
rigid->Paras_init();
spare->Paras_init();
// Directly read vertices and normals (without using files)
rigid->Read_data(target_points, source_points, target_normals, source_normals);
spare->Read_data(target_points, source_points, target_normals, source_normals);
// Perform registration
rigid->Register();
spare->Register();
// Retrieve registration results
Matrix3X result = rigid->deformed_points_3X_;
Matrix3X result2 = spare->deformed_points_3X_;
// Output results to files
rigid->Output_data(outpath, "rigid");
spare->Output_data(outpath, "spare");
import pyregister
# Create objects
rigid = pyregister.RigidFricpRegistration()
spare = pyregister.NonrigidSpareRegistration()
# Directly read data from files and perform registration
rigid.Reg("data/target.ply", "data/source.ply", "./outpath0/")
spare.Reg("data/target.obj", "data/source.obj", "./outpath0/")
# Optional parameter initialization
rigid.Paras_init(useinit=False, fileinit="", maxiter=80, stop=1e-5)
reg.Paras_init(iters = 30 ,stopcoarse=1e-3,stopfine=1e-4, uselandmark = False, src = [],tar = [])
# Reset to default parameters
rigid.Paras_init()
spare.Paras_init()
# Directly pass NumPy arrays of vertices and normals
# target_p, source_p, target_n, source_n are all numpy.ndarray with shape=(3, n)
rigid.Read_data(target_p, source_p, target_n, source_n)
spare.Read_data(target_p, source_p, target_n, source_n)
# Perform registration
rigid.Register()
spare.Register()
# Retrieve registration results
deformed_rigid = rigid.deformed_points_3X_ # numpy.ndarray, shape=(3, n)
deformed_spare = spare.deformed_points_3X_
# Output registration results to files
rigid.Output_data("./outpath2/", "rigid")
spare.Output_data("./outpath2/", "spare")
Paras_init(use_init=false, file_init="", max_iter=80, stop=1e-5);
If you have an initial transformation that can be applied on the input source model to roughly align with the input target model, you can set the first two parameters .Paras_init(useinit=True , fileinit="...") to load your initial transformation. The format of the initial transformation is a 4x4 matrix([R, t; 0, 1]), where R is a 3x3 rotation matrix and t is a 3x1 translation vector. These numbers are stored in 4 rows, and separated by spaces in each row. This format is the same as the output transformation of this code. It is worth mentioning that this code will align the center of gravity of the initial source and target models by default before starting the registration process, but this operation will be no longer used when the initial transformation is provided.
You can set the last two parameters of Paras_init to control the maximum number of iteration steps and the convergence tolerance. The registration process terminates either when the maximum number of iterations is reached or when the desired accuracy is achieved.
reg.Paras_init(iters = 30 ,stopcoarse=1e-3,stopfine=1e-4, uselandmark = False, src = [],tar = [])
Because our non-rigid registration consists of two stages, we define two convergence accuracy parameters — one for the coarse stage and another for the fine stage. Similar to the rigid registration process, each stage terminates either when the maximum number of iterations is reached or when the desired accuracy is achieved.
The registration process can optionally make use of landmark points to guide the deformation. When uselandmark is set to True, the algorithm incorporates corresponding landmark pairs from the source and target point sets (src and tar) into the registration. Here, src and tar represent the IDs (indices) of the corresponding points rather than their coordinates. These landmarks provide additional geometric constraints, improving the alignment stability and accuracy, especially in regions with sparse or ambiguous surface features.
The non-rigid registration method supports meshes or point clouds. When the input is a point cloud, the normal is required. When the source surface is represented as a point cloud, the deformation graph will be constructed by the farthest point sampling (FPS) based on Euclidean distance.
The examples folder contains sample data and example programs. The steps to run the C++ example program are as follows:
-
Place main.cpp and the CMakeLists.txt from the C++ folder at the same level as the project folder.
-
In the CMakeLists.txt, replace 002hugging_face with the name of your project folder.
-
Compile using CMake.
Directory structure:
workspace/
│
├─ Lite3DRegLib/ # Library project folder
│ ├─ cpp/ # Library source code (or rename to your project name)
│ ├─ python/
│ .
│ .
│ .
│ └─ CMakeLists.txt
│
├─ main.cpp # Example program
└─ CMakeLists.txt # CMakeLists.txt for the example program; replace 002hugging_face with the project folder name (here it is Lite3DRegLib)
If you find our code or paper helps, please consider citing:
@article{zhang2021fast,
author={Juyong Zhang and Yuxin Yao and Bailin Deng},
title={Fast and Robust Iterative Closest Point},
journal={IEEE Transactions on Pattern Analysis and Machine Intelligence},
year={2022},
volume={44},
number={7},
pages={3450-3466}}
@article{yao2025spare,
author = {Yao, Yuxin and Deng, Bailin and Hou, Junhui and Zhang, Juyong},
title = {SPARE: Symmetrized Point-to-Plane Distance for Robust Non-Rigid 3D Registration},
journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence},
year = {2025},
volume = {},
number = {},
pages = {1-18},
}





