PointCloudLibrary / PointCloudLibrary/pcl
EstimateRigidTransformation in pcl::registration::TransformationEstimation3Point may give non-rigid rotations?
Nobody has claimed this yet.
- 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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