Skip to content

Add DCReg registration method (degenercy handling)#7482

Open
JokerJohn wants to merge 2 commits intoisl-org:mainfrom
JokerJohn:add_dcreg
Open

Add DCReg registration method (degenercy handling)#7482
JokerJohn wants to merge 2 commits intoisl-org:mainfrom
JokerJohn:add_dcreg

Conversation

@JokerJohn
Copy link
Copy Markdown

@JokerJohn JokerJohn commented Apr 26, 2026

Paper and reference implementation

This PR integrates ideas from DCReg into Open3D's legacy CPU registration module.

Paper: DCReg: Decoupled Characterization for Efficient Degenerate LiDAR Registration

Reference implementation and project documentation:

DCReg targets degenerate LiDAR registration. Its core idea is to decouple rotation and translation observability with Schur complements, characterize weak physical motion axes by aligning eigenspaces to coordinate axes, and stabilize weak directions through targeted eigenvalue clamping and preconditioned solving.

This Open3D PR is not a direct import of the standalone DCReg project. Instead, it ports the solver and diagnostic ideas into Open3D's existing open3d.pipelines.registration structure:

  • Open3D continues to own point cloud containers, correspondence sets, robust kernels, ICP iteration, and RegistrationResult.
  • The Open3D-native estimator uses Open3D's point-to-plane residual model and target normals.
  • A separate compatibility helper is included only for reproducing the standalone DCReg local-plane/local-frame behavior in tests and examples.
  • Dataset runners, YAML presets, visualization scripts, benchmark scripts, and parking-lot-specific preprocessing from the reference repository are not included.

Open3D integration summary

The main Open3D-native API is TransformationEstimationPointToPlaneDCReg, which can be passed to the existing registration_icp loop in the same way as
TransformationEstimationPointToPlane. It keeps the existing ICP API and
RegistrationResult behavior unchanged while replacing the 6D point-to-plane linear solve with DCReg-style Schur-complement degeneracy detection, eigenvalue clamping in the preconditioner, PCG, and robust fallback solves.

This PR also adds explicit degeneracy diagnostic APIs and a separate standalone-compatible local-plane ICP helper for reproducing the original DCReg examples without changing Open3D's standard ICP perturbation convention.

What changed

  • Added DCRegOption for solver and local-plane compatibility options.
  • Added DCRegDegeneracyAnalysis for structured degeneracy diagnostics.
  • Added TransformationEstimationPointToPlaneDCReg for Open3D-native
    point-to-plane ICP.
  • Added compute_dcreg_degeneracy_analysis for one point-to-plane ICP linearization.
  • Added registration_icp_dcreg_local and compute_dcreg_local_degeneracy_analysis for standalone-compatible kNN local-plane residuals and local body-frame SO(3) updates.
  • Added Python bindings, repr, properties, and docstrings for the new APIs.
  • Added C++ and Python tests for construction, empty correspondences, missing normals, baseline agreement, weak-geometry stability, cylinder degeneracy diagnostics, local-frame diagnostics, and Python API use.
  • Added a tutorial page documenting usage, diagnostic interpretation, references, and differences from the standalone DCReg research code.

Implementation notes

The Open3D-native estimator intentionally follows the existing legacy ICP convention:

  • registration_icp transforms the source point cloud before each estimator call.
  • The estimator solves a target/world-frame point-to-plane update.
  • Open3D applies the returned increment by left multiplication.
  • Target normals are required, matching ordinary point-to-plane ICP.

The standalone DCReg examples use a different path: kNN local-plane residuals and a local body-frame update of the form R <- R Exp(omega), t <- t + R v. That behavior cannot be reproduced inside a normal TransformationEstimation callback because the callback does not own the original source points and evolving pose state. For that reason the standalone-compatible behavior is exposed as the separate registration_icp_dcreg_local helper.

The tutorial documents this distinction explicitly so users do not compare weak-axis diagnostics from the Open3D point-to-plane normal equation against standalone DCReg parking-lot logs that use a different residual and coordinate frame.

Degeneracy diagnostics

The diagnostic result exposes:

  • full, rotational Schur, and translational Schur condition numbers
  • Schur eigenvalues and axis-aligned eigenvalues
  • weak x/y/z rotation and translation axis flags
  • coordinate-frame description
  • human-readable weak-axis descriptions
  • human-readable degeneracy summary text
  • solver path and PCG convergence information
  • rank-deficient fallback state

Rank-deficient systems use eigensolver/minimum-norm fallback diagnostics so weak axes and eigenvalues are still available even when a Schur block is singular.

Scope

This PR targets the legacy CPU registration API only. It does not add tensor/CUDA support, dataset runners, YAML presets, benchmark scripts, parking-lot-specific preprocessing, or the full standalone DCReg experiment system.

Validation

Local checks run in your own computer :

cmake --build build-dcreg --target tests pybind python-package -j2
build-dcreg/bin/tests --gtest_filter='TransformationEstimation.DCReg*:TransformationEstimation.PointToPlaneDCReg*:TransformationEstimation.DCRegLocal*'
PYTHONPATH=/home/xchu/CLionProjects/Open3D/build-dcreg/lib/python_package python3 -m pytest -q python/test/test_registration_dcreg.py
python3 util/check_style.py
git diff --check

Results:

  • C++ DCReg tests: 11 passed
  • Python DCReg tests: 9 passed
  • Style check: passed
  • Diff whitespace check: passed
  • Build targets tests, pybind, and python-package: passed

I also ran non-CI comparison logs against the standalone DCReg shifted-cylinder and parking-lot examples. The Open3D local-compatible path matches the standalone SO(3)/parking-lot behavior, while the Open3D-native point-to-plane path intentionally reports diagnostics in Open3D's target/world left-multiplied SE(3) frame.

@update-docs
Copy link
Copy Markdown

update-docs Bot commented Apr 26, 2026

Thanks for submitting this pull request! The maintainers of this repository would appreciate if you could update the CHANGELOG.md based on your changes.

@JokerJohn
Copy link
Copy Markdown
Author

Thanks for submitting this pull request! The maintainers of this repository would appreciate if you could update the CHANGELOG.md based on your changes.

I have added the requested CHANGELOG.md entry in commit 39fe627. Could a maintainer approve the workflows when convenient?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant