Bugfix for solvePnPRansac with SOLVEPNP_ITERATIVE

The current implementation overwrites the result rotation and translation in every iteration.
If SOLVEPNP_ITERATIVE was run as a refinement it will start from the incorrect initial
transformation thus  degrading the final outcome.
pull/22914/head
Tomasz Ożański 3 years ago committed by Tomasz Ożański
parent 8334ee18e6
commit d1ff87d94d
  1. 15
      modules/calib3d/src/solvepnp.cpp

@ -149,12 +149,13 @@ public:
int runKernel( InputArray _m1, InputArray _m2, OutputArray _model ) const CV_OVERRIDE int runKernel( InputArray _m1, InputArray _m2, OutputArray _model ) const CV_OVERRIDE
{ {
Mat opoints = _m1.getMat(), ipoints = _m2.getMat(); Mat opoints = _m1.getMat(), ipoints = _m2.getMat();
Mat iter_rvec = rvec.clone();
Mat iter_tvec = tvec.clone();
bool correspondence = solvePnP( _m1, _m2, cameraMatrix, distCoeffs, bool correspondence = solvePnP( _m1, _m2, cameraMatrix, distCoeffs,
rvec, tvec, useExtrinsicGuess, flags ); iter_rvec, iter_tvec, useExtrinsicGuess, flags );
Mat _local_model; Mat _local_model;
hconcat(rvec, tvec, _local_model); hconcat(iter_rvec, iter_tvec, _local_model);
_local_model.copyTo(_model); _local_model.copyTo(_model);
return correspondence; return correspondence;
@ -313,7 +314,13 @@ bool solvePnPRansac(InputArray _opoints, InputArray _ipoints,
ipoints_inliers.resize(npoints1); ipoints_inliers.resize(npoints1);
try try
{ {
result = solvePnP(opoints_inliers, ipoints_inliers, cameraMatrix, if (flags == SOLVEPNP_ITERATIVE && !useExtrinsicGuess)
{
rvec = _local_model.col(0).clone();
tvec = _local_model.col(1).clone();
useExtrinsicGuess = true;
}
result = solvePnP(opoints_inliers, ipoints_inliers, cameraMatrix,
distCoeffs, rvec, tvec, useExtrinsicGuess, distCoeffs, rvec, tvec, useExtrinsicGuess,
(flags == SOLVEPNP_P3P || flags == SOLVEPNP_AP3P) ? SOLVEPNP_EPNP : flags) ? 1 : -1; (flags == SOLVEPNP_P3P || flags == SOLVEPNP_AP3P) ? SOLVEPNP_EPNP : flags) ? 1 : -1;
} }

Loading…
Cancel
Save