Open3D icon indicating copy to clipboard operation
Open3D copied to clipboard

Add Symmetric ICP Implementation

Open eclipse0922 opened this issue 5 months ago • 1 comments

Add Symmetric ICP Implementation for Improved Point Cloud Registration

Type

  • [ ] Bug fix (non-breaking change which fixes an issue): Fixes #
  • [x ] New feature (non-breaking change which adds functionality). Resolves #
  • [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) Resolves #

Motivation and Context

This PR introduces a Symmetric ICP (Iterative Closest Point) algorithm implementation.

Key Benefits:

  • Improved accuracy: Bidirectional error minimization reduces registration bias
  • Better convergence: More stable optimization through symmetric error terms
  • Noise robustness: Less sensitive to outliers and measurement noise
  • Partial overlap handling: Better performance when point clouds have limited overlap

This implementation follows the symmetric point-to-plane error formulation where the objective function minimizes: E = Σ [(p_s - p_t) · n_t]² + [(p_s - p_t) · n_s]² where p_s, p_t are corresponding points and n_s, n_t are their respective normals.

Checklist:

  • [x ] I have run python util/check_style.py --apply to apply Open3D code style to my code.
  • [ x] This PR changes Open3D behavior or adds new functionality.
    • [ x] Both C++ (Doxygen) and Python (Sphinx / Google style) documentation is updated accordingly.
    • [ x] I have added or updated C++ and / or Python unit tests OR included test results (e.g. screenshots or numbers) here.
  • [x ] I will follow up and update the code if CI fails.
  • [x ] For fork PRs, I have selected Allow edits from maintainers.

Description

Implementation Details

Core Components:

  1. TransformationEstimationSymmetric class extending TransformationEstimation
  2. RegistrationSymmetricICP function following Open3D's registration API patterns
  3. Comprehensive test suite with 9 unit tests covering edge cases
  4. Python bindings for seamless integration with existing workflows

Files Added/Modified:

  • cpp/open3d/pipelines/registration/SymmetricICP.h - Header with class declaration
  • cpp/open3d/pipelines/registration/SymmetricICP.cpp - Core implementation
  • cpp/tests/pipelines/registration/SymmetricICP.cpp - Comprehensive C++ tests
  • python/test/test_symmetric_icp.py - Python test suite

API Usage

C++ API:

#include "open3d/pipelines/registration/SymmetricICP.h"

auto estimation = registration::TransformationEstimationSymmetric();
auto result = registration::RegistrationSymmetricICP(
    source, target, max_distance, init_transform, estimation, criteria);

Python API:

import open3d as o3d

estimation = o3d.pipelines.registration.TransformationEstimationSymmetric()
result = o3d.pipelines.registration.registration_symmetric_icp(
    source, target, max_distance, init_transform, estimation, criteria)

Test Results

C++ Tests (9/9 passing): [==========] Running 9 tests from 1 test suite. [----------] 9 tests from SymmetricICP [ RUN ] SymmetricICP.TransformationEstimationSymmetricConstructor [ OK ] SymmetricICP.TransformationEstimationSymmetricConstructor (0 ms) [ RUN ] SymmetricICP.TransformationEstimationSymmetricComputeRMSE [ OK ] SymmetricICP.TransformationEstimationSymmetricComputeRMSE (0 ms) [ RUN ] SymmetricICP.TransformationEstimationSymmetricComputeRMSEEmptyCorres [ OK ] SymmetricICP.TransformationEstimationSymmetricComputeRMSEEmptyCorres (0 ms) [ RUN ] SymmetricICP.TransformationEstimationSymmetricComputeRMSENoNormals [ OK ] SymmetricICP.TransformationEstimationSymmetricComputeRMSENoNormals (0 ms) [ RUN ] SymmetricICP.TransformationEstimationSymmetricComputeTransformation [ OK ] SymmetricICP.TransformationEstimationSymmetricComputeTransformation (0 ms) [ RUN ] SymmetricICP.TransformationEstimationSymmetricComputeTransformationEmptyCorres [ OK ] SymmetricICP.TransformationEstimationSymmetricComputeTransformationEmptyCorres (0 ms) [ RUN ] SymmetricICP.TransformationEstimationSymmetricComputeTransformationNoNormals [ OK ] SymmetricICP.TransformationEstimationSymmetricComputeTransformationNoNormals (0 ms) [ RUN ] SymmetricICP.RegistrationSymmetricICP [ OK ] SymmetricICP.RegistrationSymmetricICP (36 ms) [ RUN ] SymmetricICP.RegistrationSymmetricICPConvergence [ OK ] SymmetricICP.RegistrationSymmetricICPConvergence (4 ms) [----------] 9 tests from SymmetricICP (41 ms total) [ PASSED ] 9 tests.

Test Coverage:

  • ✅ Constructor and basic functionality
  • ✅ RMSE computation with various input conditions
  • ✅ Transformation estimation with perfect and noisy correspondences
  • ✅ Edge cases: empty correspondences, missing normals
  • ✅ End-to-end registration with convergence validation
  • ✅ Robust handling of large-scale point clouds (50+ points)

Code Quality

Style Compliance:

  • ✅ All files pass check_style.py validation
  • ✅ 80-character line limit compliance
  • ✅ Consistent indentation and formatting
  • ✅ Proper Doxygen documentation
  • ✅ Memory-safe smart pointer usage

Design Patterns:

  • Follows existing Open3D registration framework patterns
  • Consistent with ColoredICP and standard ICP implementations
  • Supports robust kernels through the same interface
  • Maintains backward compatibility

Integration

This implementation integrates seamlessly with Open3D's existing registration pipeline:

  • Reuses existing RegistrationICP infrastructure
  • Compatible with current convergence criteria
  • Supports all robust kernel types
  • Maintains consistent error handling patterns

The Symmetric ICP method provides users with an additional tool for challenging registration scenarios while maintaining the familiar Open3D API design.

eclipse0922 avatar Jun 15 '25 15:06 eclipse0922

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

update-docs[bot] avatar Jun 15 '25 15:06 update-docs[bot]

I've noticed some failing test cases, but they don't appear to be connected to my recent modifications. Am I responsible for addressing them?

eclipse0922 avatar Jun 16 '25 02:06 eclipse0922

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB