-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Covariance estimation for bundle adjustment with Schur elimination #2610
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
|
Very nice, thanks! I will review this in more details on Monday. |
|
Let me restructure this now to support cross-pose covariance and also covariance for other parameters. |
|
New feature arised from the new update:
The testing example is updated in the PR description to incorporate tests for the first two features in the new update. |
| return true; | ||
| } | ||
|
|
||
| bool BundleAdjustmentCovarianceEstimatorCeresBackend::Compute() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to call the two methods "ComputePoseCov" and "ComputePoseAndPointCov" ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first method is to indeed compute pose covariance, but the second is to compute the covariance of all variables except for the points, as described in the header, and I felt that ComputePoseAndOtherVariablesCov is too long here.
|
Thanks, great work. |
|
@B1ueber2y thank you for this contribution. I am trying to port most of your math into my custom SfM pipeline for estimating cov for poses, and it works great for normal scenes; however for some scenes it either fails or the cov is inf, and I am not sure why. These seems to happen in scenes where there are some poses not well constrained, and I can figure out the exact cause: weak connections (constraints) for these poses, or something else. The failure is in "Simplicial LDLT for computing L_inv failed" with "NumericalIssue if the matrix.appears to be negative." |
Hey. For those poses that are not well constrained, it is possible that there is rank deficiency (or large condition number) when inverting the Hessian, resulting in failures. This actually makes sense since the covariance on certain direction would be infinite, and is not useful to inspect for downstream applications. You would need to either remove the ambiguity by adding additional constraints, or resort to more advanced techniques to deal with the nullspace (e.g., https://dspace.cvut.cz/bitstream/handle/10467/108057/F3-D-2023-Polic-Michal-Polic%20-%20disertacni%20prace.pdf). Thanks! |
|
@B1ueber2y Makes sens, thank you. Is it possible to detect only which poses are not well constrained? That in itself would be a valuable info to have for the SfM |
The rank deficiency may not be specific to one pose, but can be a global behavior. For example, if the Gauge is not constrained, all the poses can be ambiguous up to a similarity transformation, but the relative poses are well constrained. |
|
Gauge is constrained on all degrees of freedom (first camera pose is constant), except explicit lock on scale (though it is constrained too indirectly by the relative pose loss) |
This PR contains the covariance estimation for bundle adjustment with handcrafted Schur elimination, which has been forever missing from the ceres solver. Also, the interface for world_from_cam to cam_from_world conversion for the 6x6 covariance is provided with the adjoint feature from #2598
This is a practically extremely useful feature since the ceres covariance computation will generally fail for large-scale bundle adjustment problem mainly due to poorly conditioned 3D points. Many of these points generally cannot be easily identified with heuristics such as triangulation angles, making the ceres covariance computation intractable. Here are some examples of this long standing issue in the ceres development thread (seems that they stop developing this feature):
https://groups.google.com/g/ceres-solver/c/719fVUZqOZk
https://groups.google.com/g/ceres-solver/c/1SrLa1Pr8D4
With this new feature we will be able to reliably extract covariance from the bundle adjustment problem as long as the camera poses are well constrained (i.e. without Gauge ambiguity), even with poorly conditioned points. The covariance computation will also be faster with the use of Schur elimination.
Here is a minimal testing example in Python (If we feel necessary I can also try to write a unit test in C++). To be able to run the test one only needs a bundle adjusted COLMAP SfM model without rank deficiency. I am using the SfM model produced by the pycolmap example from here: https://github.com/colmap/colmap/blob/main/pycolmap/example.py