PointCloudLibrary / PointCloudLibrary/pcl

EstimateRigidTransformation in pcl::registration::TransformationEstimation3Point may give non-rigid rotations?

Open
#1,660 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

status: stale
Dominant language
C++
Stars
11.1k
Forks
4.7k
Avg merge
4d 10h
Merged PRs (30d)
6

Description

Expected Behavior

I would expect EstimateRigidTransformation to always give invertible affine transformations. In the case of TransformationEstimation3Point I would expect the linear part of the computed transformation to be always a rotation.

For instance, if the source cloud is composed of points (0,0,0), (1,0,0) and (-1,0,0) and target cloud is composed of (0,0,0), (0,1,0) and (0,-1,0) then I would expect that estimateRigidTransformation will give me back anything of the form

0 -sin(θ) cos(θ) 0
1      0      0  0
0  cos(θ) sin(θ) 0
0      0      0  1

for example

0 -1 0 0
1  0 0 0
0  0 1 0
0  0 0 1

or

0 0 1 0
1 0 0 0
0 1 0 0
0 0 0 1

Current Behavior

This function actually gives invertible affine transformation whose linear part is a rotation when you give her two clouds in which the points define an affine plane.
But when you feed it with size 3 point clouds that are co-linear the results might be unexpected.
Every time this happens, the computed transformation's linear part will not be of full rank (it will be either rank one or null).

For instance, if the source cloud is composed of points (0,0,0), (1,0,0) and (-1,0,0) and target cloud is composed of (0,0,0), (0,1,0) and (0,-1,0) then the result will be the following transformation

0 0 0 0
1 0 0 0
0 0 0 0
0 0 0 1

Possible Solution

I think that there should be a test to check whether one of the point clouds has all three points identical, and that in that case, the computed transform should be a translation (the linear part is identity).

I think that there should also be a test to check whether one of the point clouds has all three points co-linear, but I am not sure what the preferred answer in this case should be. If there is no unique preferred solution in this case, maybe the user should be warned.

Code to Reproduce

    pcl::registration::TransformationEstimation3Point<PointXYZ, PointXYZ> te;
    pcl::registration::TransformationEstimation3Point<PointXYZ, PointXYZ>::Matrix4 R;
    pcl::PointCloud<PointXYZ> src, tgt;
    src.resize(3); tgt.resize(3);
    src.points[0].getVector3fMap() << 0.0, 0.0, 0.0;
    src.points[1].getVector3fMap() << 1.0, 0.0, 0.0;
    src.points[2].getVector3fMap() << -1.0, 0.0, 0.0;
    std::cout << "source cloud is " << endl << src.getMatrixXfMap(3, 4, 0) << endl;
    tgt.points[0].getVector3fMap() << 0.0, 0.0, 0.0;
    tgt.points[1].getVector3fMap() << 0.0, 1.0, 0.0;
    tgt.points[2].getVector3fMap() << 0.0, -1.0, 0.0;
    std::cout << "target cloud is " << endl << tgt.getMatrixXfMap(3, 4, 0) << endl;
    te.estimateRigidTransformation(src, tgt, R);
    std::cout << "computed transformation is \n" << R << endl;

Context

Given two points P and Q , I needed a rotation that sends the first one as close as possible to the second one while fixing the origin O and such that the axis of the rotation is orthogonal both to OP and OQ. I did it using pcl::registration::TransformationEstimation3Point::estimateRigidTransform but I had to be very careful on its arguments because of this issue.

P.S. I am still wondering whether this issue is a bug or a feature.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at pcl::registration::TransformationEstimation3Point::estimateRigidTransformation and run the provided three-point collinear reproduction. Read the surrounding transformation-estimation code to understand how degenerate inputs are handled. Done should include tests for identical and collinear point clouds and a maintainer-approved behavior for the non-unique rotation case.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
computer-vision
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.