-
-
Notifications
You must be signed in to change notification settings - Fork 56.3k
Fixes and optimizations for the SQPnP solver #21702
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- optimized the calculation of qa_sum by moving equal elements outside the loop - unrolled copying of the lower triangle of omega - substituted SVD with eigendecomposition in the factorization of omega (2-3 times faster) - fixed the initialization of lambda in FOAM - added a cheirality test that checks a solution on all 3D points rather than on their mean. The old test rejected valid poses in some cases - fixed some typos & errors in comments
Eigen decomposition seems to yield larger errors in certain tests, reverted to SVD
Added nearestRotationMatrixSVD() Previous nearestRotationMatrix() renamed to nearestRotationMatrixFOAM() and reverts to nearestRotationMatrixSVD() for singular matrices
/cc @nathanrgodwin as author of initial contribution |
Fixed the order of checks in PoseSolver::solveInternal()
@victor1234 Please take a look. |
@mlourakis as I understand main improvements are:
How did you measure calculation time improvements?
In which cases? Is this a bug of implementation? Thanks |
Hi,
Your summary description is correct.
Computation time was measured in microseconds using
std::chrono::high_resolution_clock::now() and various inputs.
The old initialization of lambda caused the FOAM algorithm to diverge in
a pathological case with a singular input matrix; the latter was
reported as an issue by an SQPnP user
(terzakig/sqpnp#15).
The cheirality fix is also important as the old test sometimes caused
valid solutions to be discarded.
To compute the nullspace of matrix Omega, the SVD is used. Despite its
excellent stability, SVD is slow and does not exploit the symmetry of
our matrix. Therefore, I attempted to replace SVD with eigen
decomposition (EVD) but the results were not as accurate as with SVD. It
seems that this is an issue inherent with the EVD (rather than its
implementation) as I tried to use Eigen's SelfAdjointEigenSolver in the
OpenCV code without success.
Note here that the stand-alone implementation of SQPnP uses Eigen's
rank-revealing QR (see
https://github.com/terzakig/sqpnp/blob/e9ebcf07ac26350777548a3eefdae578f9570200/sqpnp/sqpnp.h#L205-L213)
wich is faster compared to SVD. The user is given the option to choose
between RRQR and SVD. However, as openCV seems to lack a RRQR, I had to
stick to SVD.
Hope this has cleared things up.
Best regards,
ML
On 2022-04-28 15:41, Victor wrote:
@mlourakis [1] as I understand main improvements are:
* fixed some typos & errors in comments
* calculation time optimization
* fixies: initialization of lambda, cheirality test
How did you measure calculation time improvements?
What was practically affected by the fixies? I mean in which cases the old solution did not work?
> Eigen decomposition seems to yield larger errors in certain tests, reverted to SVD
In which cases? Is this a bug of implementation?
Thanks
--
Reply to this email directly, view it on GitHub [2], or unsubscribe [3].
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
Great |
@mlourakis, thank you very much for keeping OpenCV version of your code up-to-date! 👍 |
Fixes and optimizations for the SQPnP solver * Fixes and optimizations - optimized the calculation of qa_sum by moving equal elements outside the loop - unrolled copying of the lower triangle of omega - substituted SVD with eigendecomposition in the factorization of omega (2-3 times faster) - fixed the initialization of lambda in FOAM - added a cheirality test that checks a solution on all 3D points rather than on their mean. The old test rejected valid poses in some cases - fixed some typos & errors in comments * reverted to SVD Eigen decomposition seems to yield larger errors in certain tests, reverted to SVD * nearestRotationMatrixSVD Added nearestRotationMatrixSVD() Previous nearestRotationMatrix() renamed to nearestRotationMatrixFOAM() and reverts to nearestRotationMatrixSVD() for singular matrices * fixed checks order Fixed the order of checks in PoseSolver::solveInternal()
This PR mirrors to OpenCV changes made recently to the official SQPnP implementation
Pull Request Readiness Checklist
Patch to opencv_extra has the same branch name.