Skip to content

Fix ransac issue "SolvePnPRansac Fails because calls to solvePnP with less than 6 points"#19492

Closed
Dylancer1998 wants to merge 2 commits intoopencv:3.4from
Dylancer1998:fix-ransac-issue
Closed

Fix ransac issue "SolvePnPRansac Fails because calls to solvePnP with less than 6 points"#19492
Dylancer1998 wants to merge 2 commits intoopencv:3.4from
Dylancer1998:fix-ransac-issue

Conversation

@Dylancer1998
Copy link
Copy Markdown

@Dylancer1998 Dylancer1998 commented Feb 10, 2021

Firstly, I proposed this issue in there. issue #17799
I did some amendment based on this PR.

My solutions:

  • return "true" and the EPnP's result when SolvePnPRansac Fails due to there is no coplanaer data and DLT with less than 6 points. Because I think the result of EPnP may be correct, we should leave the right for user to choose whether use or not use the result.
  • provide a test data
  • provide a log for user

Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

  • I agree to contribute to the project under Apache 2 License.
  • To the best of my knowledge, the proposed patch is not based on a code under GPL or other license that is incompatible with OpenCV
  • The PR is proposed to proper branch
  • There is reference to original bug report and related work
  • There is accuracy test, performance test and test data in opencv_extra repository, if applicable
    Patch to opencv_extra has the same branch name.
  • The feature is well documented and sample code can be built with the project CMake
force_builders_only=linux,docs

@Dylancer1998
Copy link
Copy Markdown
Author

Dylancer1998 commented Feb 10, 2021

@catree Could you help me review this PR? Thanks!

@alalek
Copy link
Copy Markdown
Member

alalek commented Feb 10, 2021

It makes sense to start from the regression test. Test is here

@Dylancer1998
Copy link
Copy Markdown
Author

It makes sense to start from the regression test. Test is here

Is there any problem? Could you guide me what should I do?

Copy link
Copy Markdown
Contributor

@catree catree left a comment

Choose a reason for hiding this comment

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

Quick review.

Probably we could try to fuse the two PRs.

distCoeffs, rvec, tvec, useExtrinsicGuess,
(flags == SOLVEPNP_P3P || flags == SOLVEPNP_AP3P) ? SOLVEPNP_EPNP : flags) ? 1 : -1;
}
catch(...){
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.

I think it is better to have catch (const cv::Exception& e).

And log also e.what(). This way, if another type of exception is thrown from solvePnP it will be logged.

Copy link
Copy Markdown
Author

@Dylancer1998 Dylancer1998 Feb 11, 2021

Choose a reason for hiding this comment

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

Ok. I agree with you. I have already commited the modification.

camera_mat.at<float>(1, 2) = 353.712;
camera_mat.at<float>(2, 2) = 1.f;

pts3ds = {
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.

/build/precommit_linux64/3.4/opencv/modules/calib3d/test/test_solvepnp_ransac.cpp:2247:5: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]
/build/precommit_linux64/3.4/opencv/modules/calib3d/test/test_solvepnp_ransac.cpp:2238:12: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]
/build/precommit_linux64/3.4/opencv/modules/calib3d/test/test_solvepnp_ransac.cpp:2238:12: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]
/build/precommit_linux64/3.4/opencv/modules/calib3d/test/test_solvepnp_ransac.cpp:2238:12: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]
/build/precommit_linux64/3.4/opencv/modules/calib3d/test/test_solvepnp_ransac.cpp:2258:5: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]
/build/precommit_linux64/3.4/opencv/modules/calib3d/test/test_solvepnp_ransac.cpp:2249:12: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]
/build/precommit_linux64/3.4/opencv/modules/calib3d/test/test_solvepnp_ransac.cpp:2249:12: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]
/build/precommit_linux64/3.4/opencv/modules/calib3d/test/test_solvepnp_ransac.cpp:2249:12: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]

See the buildbot (you can click on the build numbers): https://pullrequest.opencv.org/#/summary/opencv

This requires C++11 and 3.4 OpenCV cannot require C++11 features.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Please help me what should I do to fix the build failures?

Copy link
Copy Markdown
Contributor

@mightbxg mightbxg Feb 11, 2021

Choose a reason for hiding this comment

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

Initializer list for vector is a C++11 feature which should not be used here. You can either push_back the points to the vector, or use cv::Mat instead. See my PR here.

catch(const cv::Exception& e)
{
CV_LOG_DEBUG(e.what());
CV_LOG_DEBUG(NULL, "Broken implementation for DLT algorithm needs at least 6 points for pose estimation. Fallback to EPnP.");
Copy link
Copy Markdown
Contributor

@mightbxg mightbxg Feb 11, 2021

Choose a reason for hiding this comment

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

Log message here is inaccurate. You cannot just presume that the Exception can only be caused by DLT algorithm.

Comment on lines +329 to +340
if(_inliers.needed())
{
Mat _local_inliers;
for (int i = 0; i < npoints; ++i)
{
if((int)_mask_local_inliers.at<uchar>(i) != 0) // inliers mask
_local_inliers.push_back(i); // output inliers vector
}
_local_inliers.copyTo(_inliers);
}

return true;
Copy link
Copy Markdown
Contributor

@mightbxg mightbxg Feb 11, 2021

Choose a reason for hiding this comment

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

Unnecessary codes (L329-L340)

@mightbxg
Copy link
Copy Markdown
Contributor

@Johnzdh
This PR seems just a duplicate of mine #19253

@Dylancer1998
Copy link
Copy Markdown
Author

Dylancer1998 commented Feb 11, 2021

@Johnzdh
This PR seems just a duplicate of mine #19253

Great job~ Thanks!
I saw your previous PR was to return false when triggered the DLT error, so I wanted to fixed it.
I agree with your later PR. When your later PR is merged, I will close this one.

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.

4 participants