Skip to content

Improve solvePnPRansac#9086

Merged
opencv-pushbot merged 1 commit intoopencv:masterfrom
catree:improve_solvePnPRansac
Jul 14, 2017
Merged

Improve solvePnPRansac#9086
opencv-pushbot merged 1 commit intoopencv:masterfrom
catree:improve_solvePnPRansac

Conversation

@catree
Copy link
Copy Markdown
Contributor

@catree catree commented Jul 3, 2017

This pullrequest changes

This PR is an attempt to improve and clarify the "algorithm" behind solvePnPRansac, see also #8782.
From what I have understood of the code:

  • when the number of input points is equal to the number of model points, rvec and tvec are estimated two times: once here and another time here
  • this should be unnecessary and this PR "short-circuits" by calling directly solvePnP
  • the useExtrinsicGuess parameters has no effect as ransac_kernel_method is set by default to SOLVEPNP_EPNP or SOLVEPNP_P3P, SOLVEPNP_AP3P by the user and is not used for the final call to solvePnP
  • with this PR, useExtrinsicGuess is used with solvePnP with all the inliers
  • document a little the behavior of solvePnPRansac
  • resolves solvePnPRansac() returns the "wrong" rvec and tvec #9085 there is an issue for me as the function returns the best rvec and tvec estimated during the Minimal Sample Sets step and not rvec and tvec estimated using all the inliers

Before this PR:

[----------] 3 tests from Calib3d_SolvePnPRansac
[ RUN      ] Calib3d_SolvePnPRansac.accuracy
mode: 0, method: 0 -> 100% (err < 5.08272e-06)
mode: 0, method: 1 -> 100% (err < 1.90336e-05)
mode: 0, method: 2 -> 100% (err < 6.83566e-05)
mode: 0, method: 3 -> 100% (err < 1.48587e-06)
mode: 0, method: 4 -> 100% (err < 3.88479e-05)
mode: 0, method: 5 -> 100% (err < 0.000988152)
mode: 1, method: 0 -> 100% (err < 0.000211219)
mode: 1, method: 1 -> 100% (err < 1.80233e-06)
mode: 1, method: 2 -> 100% (err < 1.70374e-05)
mode: 1, method: 3 -> 100% (err < 5.7117e-06)
mode: 1, method: 4 -> 100% (err < 5.93684e-06)
mode: 1, method: 5 -> 100% (err < 0.00151996)
[       OK ] Calib3d_SolvePnPRansac.accuracy (68 ms)

With this PR:

[----------] 3 tests from Calib3d_SolvePnPRansac
[ RUN      ] Calib3d_SolvePnPRansac.accuracy
mode: 0, method: 0 -> 100% (err < 1.15535e-07)
mode: 0, method: 1 -> 100% (err < 0.000260042)
mode: 0, method: 2 -> 100% (err < 0.00487855)
mode: 0, method: 3 -> 100% (err < 9.49898e-08)
mode: 0, method: 4 -> 90% (err < 0.0643757)
mode: 0, method: 5 -> 80% (err < 0.063708)
mode: 1, method: 0 -> 100% (err < 5.12943e-07)
mode: 1, method: 1 -> 100% (err < 1.98415e-07)
mode: 1, method: 2 -> 100% (err < 1.5598e-07)
mode: 1, method: 3 -> 100% (err < 0.00293191)
mode: 1, method: 4 -> 100% (err < 0.00293468)
mode: 1, method: 5 -> 100% (err < 0.000291018)
[       OK ] Calib3d_SolvePnPRansac.accuracy (76 ms)

At first sight, the accuracy is worse. But before the function returned the best rvec and tvec estimated during the Minimal Sample Sets step and now rvec and tvec estimated using all the inliers, the
RANSAC parameters could be not optimal here.

Mat _local_inliers;
for(int i = 0; i < npoints; i++)
{
_local_inliers.push_back(i);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use push_back here, required size is known.

{
_local_inliers.push_back(i);
}
_local_inliers.copyTo(_inliers);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy can be avoided:

_inliers.create(...);
Mat _local_inliers = _inliers.getMat()
//fill _local_inliers

@catree
Copy link
Copy Markdown
Contributor Author

catree commented Jul 4, 2017

Fix also an issue when _local_model is empty after the first step.
I did some tests, unfortunately there should be (almost) no improvement between returning rvec and tvec estimated from the Minimal Sample Sets step and estimated using all the inliers, at least on my test case (video).
Same thing if I tweak the code to use SOLVEPNP_ITERATIVE initialized with the camera pose estimated from the MSS step for the final pose estimation (video). I am still tempted to say that the best logic should be to use for the final pose estimation an iterative method initialized with the results of the MSS step.

@tompollok
Copy link
Copy Markdown
Contributor

@catree is the source code + dataset that you used for the video available somewhere?

@sovrasov
Copy link
Copy Markdown
Contributor

sovrasov commented Jul 5, 2017

👍

@catree
Copy link
Copy Markdown
Contributor Author

catree commented Jul 5, 2017

@catree is the source code + dataset that you used for the video available somewhere?

@tompollok No, it is my own data.

… number of model points. Enable useExtrinsicGuess parameter. Return rvec and tvec estimated using all the inliers instead of the best rvec and tvec estimated during the Minimal Sample Sets step. Document the behavior of solvePnPRansac.
@catree catree force-pushed the improve_solvePnPRansac branch from 8e18018 to 98c78e0 Compare July 5, 2017 11:18
@HagegeR
Copy link
Copy Markdown

HagegeR commented Jul 9, 2017

could this make it into 3.3?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

solvePnPRansac() returns the "wrong" rvec and tvec

6 participants