Skip to content

Fast, robust, and lightweight 3D registration library. Supports Rigid (Fast-ICP) and Non-Rigid (SPARE) algorithms with interactive visualization.

License

Notifications You must be signed in to change notification settings

USTC3DV/Lite3DReg

Repository files navigation



3

Lightweight lib for 3D rigid registration and non-registration with robustness and efficiency

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.

Key features

  • 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.

Rigid registration IEEE 2021

Non-rigid registration IEEE 2025

Huggingface & Gradio Visualization

Huggingface Space:

Interactive Interface:

image

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.

Lite3DReg repository layout

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

Dependencies

  1. Eigen-3.4.0
  2. OpenMesh-8.1
  3. (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

Compilation

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.

Interface

C++

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");

Python

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")

parameters

Rigid(fricp)

Paras_init(use_init=false, file_init="", max_iter=80, stop=1e-5);

Initialization support

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.

Iteration steps and Convergence accuracy

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.

NonRigid(spare)

reg.Paras_init(iters = 30 ,stopcoarse=1e-3,stopfine=1e-4, uselandmark = False, src = [],tar = [])

Iteration steps and Convergence accuracy

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.

landmark point support

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.

notes

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.

examples

The examples folder contains sample data and example programs. The steps to run the C++ example program are as follows:

  1. Place main.cpp and the CMakeLists.txt from the C++ folder at the same level as the project folder.

  2. In the CMakeLists.txt, replace 002hugging_face with the name of your project folder.

  3. 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)

Citation

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},
}

About

Fast, robust, and lightweight 3D registration library. Supports Rigid (Fast-ICP) and Non-Rigid (SPARE) algorithms with interactive visualization.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •