add estimateAffine3D overload that implements Umeyama's algorithm#19689
add estimateAffine3D overload that implements Umeyama's algorithm#19689opencv-pushbot merged 1 commit intoopencv:masterfrom
Conversation
| Mat u,d,vt; | ||
| SVD::compute(cov, d, u, vt, SVD::MODIFY_A | SVD::FULL_UV); | ||
|
|
||
| CV_CheckGE(countNonZero(d), 2, "Points cannot be colinear"); |
There was a problem hiding this comment.
this check may throw exception, which is not a good idea for a numerical algorithm. Instead, it should provide some reasonable response, i.e. return empty matrix or maybe one of possible solutions (if there are many).
There was a problem hiding this comment.
If the points are collinear the problem is underconstrained and there is an infinite number of solutions. However it is common to throw on malformed arguments, for example if the input matrices are not the correct dimension.
E.g. CV_CheckEQ(to.checkVector(3), count, "Point sets need to have the same size"); I would consider this to be a similar case.
I would suggest extending the documentation to saying that co-linear points are not valid. Returning a possible solution would involve matching two two point sets, of which at least one lies on a line. So we would need to choose a random plane to project to to do so. It would involve quite some heuristics and would be pretty hard for the user to unravel if it goes wrong.
BTW.: I tried what happens when a collinear set of points is passed to the existing RANSAC implementation:
import cv2
import numpy as np
a = np.array([[1., 1, 1, 1],[0, 0, 0, 0],[0, 0, 0, 0]]).T
r, o, i = cv2.estimateAffine3D(a, a)
print(o, r)
returns:
[[0.5 0. 0. 0.5]
[0. 0. 0. 0. ]
[0. 0. 0. 0. ]] 1
Should I maybe open an issue, at least this should probably not report a successful execution.
|
@andy-held, thank you for the contribution. |
|
I wasn't sure about the use of It could be used as core of the RANSAC loop, it needs 4 points at least. The advantage compared to the linear equation solving is that the resulting transformation is guaranteed to have an orthonormal rotation matrix (and can also force it to not be a reflection). |
|
jenkins cn please retry a build |
|
I thought about my last statement and looked it up, I was wrong. The algorithm needs only 3 points, as it only calculates a transformation with 7 degrees of freedom. I adjusted my code accordingly and also noted it in the comments explicitely. |
Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
Patch to opencv_extra has the same branch name.
Added an estimateAffine3D overload that implements Umeyama's algorithm. Compared to the existing function, this has the advantage that it can optimize scale, will always return a rotation matrix and can force the rotation to not be a reflection, but has the disadvantage that it is not as robust against outliers.
I would appreciate feedback regarding the function signature my Mat use, as I am not as versed with it.