Skip to content
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

[Multiview] Add lambda twist p3p solver #1500

Closed
wants to merge 15 commits into from

Conversation

rjanvier
Copy link
Member

@rjanvier rjanvier commented Apr 5, 2019

cc Mikael Persson (@midjji)

This PR contains the code the of the P3P method exposed in Persson M., Nordberg K., Lambda Twist: An Accurate Fast Robust Perspective Three Point (P3P) Solver, ECCV 2018.

  • I had just adapted the code present in the original repository (https://github.com/midjji/lambdatwist-p3p) to Eigen/openMVG. I kept some comments and maybe some duplicated methods w.r.t what we already have in openMVG. I think further refinements, if needed, are out of my league and maybe @midjji and @pmoulon you could now further discuss about how to best integrate lambda twist in openMVG.

  • According to discussion we had with Mikael, the code is now MPL-2 licensed (instead of the original GPL-3.0 scheme) and the method is named in honor of Klas Nordberg.

The implementation is tested and functional. I made some extensive real life tests, using it for my main solver in several dataset (one was about 7790 HR images of Château de Chambord ;)). It's very stable and plays nicely with AC-RANSAC. I think it should be default p3p solver in openMVG.

Thank you so much to Klas Nordberg and Mikael Persson for making this code public under a permissive license.

@rjanvier rjanvier changed the title Develop lambda twist [Multiview] Add lambda twist p3p solver Apr 5, 2019
@pmoulon
Copy link
Member

pmoulon commented Apr 11, 2019

Thank you guys. I will check why we have a compilation error for CLANG and VSTUDIO ;-) and make a code review.

@midjji
Copy link

midjji commented Apr 14, 2019 via email

@midjji
Copy link

midjji commented Apr 14, 2019 via email

@rjanvier
Copy link
Member Author

rjanvier commented Apr 14, 2019

The first own, the vector.
@midjji
Ok, here I kept the interface we have for Ke's solver. I will stick to your implementation then.

@midjji
Copy link

midjji commented Apr 15, 2019 via email

@pmoulon
Copy link
Member

pmoulon commented Apr 15, 2019

@midjji Thank you for your feedback.

I agree that each solver should use the best numerical precision and sometimes it forces to uses a specific root solver that could be optimized for speed and accuracy. We will keep your specific root solver. I was trying to see if we could factorize some code. We are glad to have your feedback.

Regarding vector vs array. In order to keep some genericity due to the fact that some solver can return multiple solutions, we need vector at the end. So std::array could be used inside the solver and then only a single solution will be returned in your case.

@rjanvier
Copy link
Member Author

rjanvier commented Apr 16, 2019

@pmoulon it returns up to 4 solutions like any other p3p solver.

so the question is : should we keep the std::vector (for sake of consistency with the other p3p interfaces in openMVG) or use arrays (to be truly fair with the original code and in order to maximize speed) in computePosesNordberg?
Even if i think the speed is not an issue for us, since openMVG does not target (primarly) real time applications, I think it's not a big dealhere for openMVG if we stick with the original code, since the call of computePosesNordberg is wrapped inside another function anyway (P3PSolver_Nordberg::solve) and it hides the fact we use preallocated arrays vs. dynamic vectors.

@RamadanAhmed
Copy link

I think you should add #include in solver_resection_p3p_nordberg.cpp to compile in visual studio

@rjanvier
Copy link
Member Author

I think you should add #include in solver_resection_p3p_nordberg.cpp to compile in visual studio

Thanks @RamadanAhmed have you any idea of the specific missing include?

@midjji
Copy link

midjji commented Apr 16, 2019 via email

@RamadanAhmed
Copy link

RamadanAhmed commented Apr 16, 2019

I think you should add #include in solver_resection_p3p_nordberg.cpp to compile in visual studio

Thanks @RamadanAhmed have you any idea of the specific missing include?

"#include array" sorry I forget to mention :)

@rjanvier
Copy link
Member Author

Ok if I understand well we keep the vector in the `computePosesNordberg``?
For the rotation we use a the matrix parametrisation in openMVG so it's that we want!

@pmoulon
Copy link
Member

pmoulon commented Apr 16, 2019

@rjanvier I agree with your comment #1500 (comment)

  • Sorry if I was not clear: Using the array in the computePosesNordberg is totally fine. We have to keep the vector<> only in the generic interface that will be plugged into the kernel for robust estimation.

Congrats team we are very close to having another minimal solver in Develop to be tested! 🎉

@RamadanAhmed
Copy link

RamadanAhmed commented Apr 17, 2019

I have also tested it and it works much better than P3P_Ke, I think it should be the main solver for p3p

@pmoulon
Copy link
Member

pmoulon commented Apr 17, 2019

Thank you @RamadanAhmed for testing the WIP feature. Appreciated!

  • Once I will merge to develop, once it is tested, I will make it default.

We just need to test its behavior for pinhole and 360 images.

@rjanvier Seems like a minor concern is still there to the variable fx here https://app.codacy.com/app/pmoulon/openMVG/pullRequest?prid=3389059 (I can fix it)

@rjanvier
Copy link
Member Author

@pmoulon I think allocating fx/fpx into the loop could impact the perfomance... AFAIK it really depends on the compiler so I haven't fixed it on purpose.

@midjji
Copy link

midjji commented Apr 18, 2019 via email

@midjji
Copy link

midjji commented Apr 18, 2019 via email

@rjanvier
Copy link
Member Author

@midjji it's an equirectangular projection model. I did a test yesterday with 360 images, lambda twist works at least as well as Ke's solver (regarding behavior). We use bearing vectors as input (not 2 coordinates in sensor's frame) and it seems you use a bearing vector formulation too in the solver, so it's general enough but maybe I'm wrong and I'm missing some important points here, please let me know. thanks a lot!

@rjanvier
Copy link
Member Author

Ok my bad, it seems that the spherical model violate the assumption that all points must have the same signed distance w.r.t to the camera center. Am I right?
It seems that it worked well on my spherical dataset but it's certainly due to the fact I have always 3 "good" points lying in one hemisphere... I made a simple synthetic test with 3 points well distributed on the sphere and it shows that it's not working. You said you have a possible "fix"? Else it's not a big deal, I think we can easily restrict the use of lambda twist to the pinhole model and keep Ke's solver for spherical cameras.

@rjanvier
Copy link
Member Author

rjanvier commented Apr 19, 2019

please forget my last comment, my synthetic test was wrong.

@midjji
Copy link

midjji commented Apr 21, 2019 via email

@midjji
Copy link

midjji commented Apr 22, 2019 via email

@rjanvier
Copy link
Member Author

rjanvier commented Apr 22, 2019

@midjji 360 camera works on my experiments (both real cases and synthetics). I'm not 100% sure though because I do not have a strong mathematical background (I came from an "humanities" background) and I'm not able to extract by myself the "proof" from your code/paper.
Moreover in the paper one of the prerequisite of your methods is "since the parametersλkis the signed distance from the camera center for each 3D point,λ1, λ2,andλ3 are required to be positive and real. This is a geometric feasibility condition on the solutions, which implies that all three 3D points are “in front of” the camera." and it seems to contradict the way spherical projection work and my empirical observations ;).
Regarding the L2 normalization, your are right, I will revert the commit where I removed it because I assumed we use unit vectors in openMVG ("normalized bearing vectors") but I just saw that in the case of pinhole camera we still use straight homogeneous coordinates.

@pmoulon pmoulon added this to the 1.5 milestone May 2, 2019
@pmoulon pmoulon self-assigned this May 2, 2019
pmoulon pushed a commit that referenced this pull request May 7, 2019
- few style modifications (spaces etc)
- Add back and complete docstrings from author

- fix some code formating issues thanks @pmoulon
- move functions into the cpp
pmoulon added a commit that referenced this pull request May 7, 2019
- add resection::SolverType::P3P_NORDBERG_ECCV18 to the SfM_Localizer
- set resection::SolverType::P3P_NORDBERG_ECCV18 as the default p3p
solver for sequential SfM v1, v2 and the image localization client.
@pmoulon
Copy link
Member

pmoulon commented May 7, 2019

Merged by b09174a and 0a4faee

Thank you @midjji, @rjanvier

@RamadanAhmed This feature is ready to test, feel free to try it in the develop branch and provide any feedback.

@pmoulon pmoulon closed this May 7, 2019
@vadixidav vadixidav mentioned this pull request Dec 16, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants