Skip to content

Remove dead code corresponding to SOLVEPNP_DLS and SOLVEPNP_UPNP flags #27358

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

Open
wants to merge 1 commit into
base: 5.x
Choose a base branch
from

Conversation

s-trinh
Copy link
Contributor

@s-trinh s-trinh commented May 26, 2025

Cf #27330


SOLVEPNP_DLS and SOLVEPNP_UPNP flags are internally mapped to SOLVEPNP_EPNP for more than 10 years.
Remove these functions in OpenCV 5 to clean-up the codebase and avoid potential misconceptions where someone thinks he uses DLS/UPnP methods while it is just internally mapped to EPnP.

Pros:

  • remove these flags to avoid potential confusion (there are probably some CV papers that compare against DLS and UPnP using OpenCV code...)
  • remove dead code

Cons:

  • API breaking change

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 another license that is incompatible with OpenCV
  • The PR is proposed to the proper branch
  • There is a reference to the 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

@asmorkalov
Copy link
Contributor

@s-trinh Is the PR ready for review?

@s-trinh
Copy link
Contributor Author

s-trinh commented Jun 18, 2025

Hello @ivashmak

In OpenCV 4, SOLVEPNP_DLS and SOLVEPNP_UPNP methods (for cv::solvePnP()) have been deactivated and silently remapped to SOLVEPNP_EPNP, see #3828
It has been the case for more than 10 years now.
OpenCV 5 is the opportunity to remove these two flags.

When searching, it looks like the DLS method suffers from a singularity in the rotation parameterization, eg. from or this paper:

image

image

I have seen that in USAC:

if (min_sample_size == 3) {
min_solver = P3PSolver::create(points, calib_points, K1);
non_min_solver = DLSPnP::create(points, calib_points, K1);

an implementation of the DLS method is used.

My questions are:

  • any comment, objection about the removal of the SOLVEPNP_DLS or SOLVEPNP_UPNP methods in cv::solvePnP() methods?
  • should the USAC PnP use another method instead of the DLS method?
  • any reason to not use directly the SOLVEPNP_AP3P (or SOLVEPNP_P3P) in OpenCV as a P3P solver in USAC?

Thanks.

These flags are internally mapped to SOLVEPNP_EPNP for more than 10 years and thus unavailable since then.
@s-trinh s-trinh force-pushed the clean_remove_DLS_UPNP_methods branch from 4993115 to 1c72264 Compare June 21, 2025 02:20
@ivashmak
Copy link
Contributor

ivashmak commented Jun 22, 2025

Hi @s-trinh,

  • If SOLVEPNP_DLS and SOLVEPNP_UPNP flags are internally mapped to SOLVEPNP_EPNP, then it is probably safe to remove them. I do not have any objection about it.
  • USAC PnP uses DLS on a non-minimal (>3) sample. After using DLS solver, USAC verifies that the DLS solution is better (in terms of inliers) than the so-far-the-best. If DLS has problems with singularity, which results in poor estimation, then this solution will not be accepted in USAC. However, if DLS returns a solution with a high number of inliers, but is degenerate, then this is a potential risk. Empirically, have you noticed this problem with running experiments? There is a least-squares PnP solver implemented in USAC, which should not return a degenerate result, but it often gives numerically worse models than DLS.
  • P3P solver in USAC is an optimized version of P3P solver, which is faster than the one in OpenCV. AP3P solver is a potentially better solver than P3P. However, I am not sure if it is worth to replace it. First, USAC P3P is very fast, which is very important in RANSAC/USAC paradigm, when many samples are drawn. Second, the final solution is optimized with a non-minimal sample. It is very rare that USAC will return a solution directly from P3P solver (a minimal sample).

@asmorkalov asmorkalov added category: calib3d cleanup Code cleanup (e.g, drop legacy C-API, legacy unmaintained code) labels Jun 22, 2025
@s-trinh
Copy link
Contributor Author

s-trinh commented Jun 22, 2025

Thanks for the answers @ivashmak


However, if DLS returns a solution with a high number of inliers, but is degenerate, then this is a potential risk. Empirically, have you noticed this problem with running experiments?

I have not encountered these issues, at least not situations where the DLS singularity could have been specifically pinpointed.
Main reason is to clean-up the code and avoid issue where someone thinks he is using SOLVEPNP_DLS or SOLVEPNP_UPNP while it is SOLVEPNP_EPNP under the hood and to try to improve the library.


There is a least-squares PnP solver implemented in USAC, which should not return a degenerate result, but it often gives numerically worse models than DLS.

Is it this one?

class PnPMinimalSolver6PtsImpl : public PnPMinimalSolver6Pts {


P3P solver in USAC is an optimized version of P3P solver, which is faster than the one in OpenCV. AP3P solver is a potentially better solver than P3P.

I have experienced with poor accuracy with the P3P solver in cv::solvePnP() and when looking online I have found:

/// Given 3D distances between three points and cosines of 3 angles at the apex, calculates
/// the lengths of the line segments connecting projection center (P) and the three 3D points (A, B, C).
/// Returned distances are for |PA|, |PB|, |PC| respectively.
/// Only the solution to the main branch.
/// Reference : X.S. Gao, X.-R. Hou, J. Tang, H.-F. Chang; "Complete Solution Classification for the Perspective-Three-Point Problem"
/// IEEE Trans. on PAMI, vol. 25, No. 8, August 2003
/// \param lengths Lengths of line segments up to four solutions.
/// \param distances Distance between 3D points in pairs |BC|, |AC|, |AB|.
/// \param cosines Cosine of the angles /_BPC, /_APC, /_APB.
/// \returns Number of solutions.
/// WARNING: NOT ALL THE DEGENERATE CASES ARE IMPLEMENTED

which seem to corroborate with my experiments.


So actually it could be a good idea to replace the P3P in cv::solvePnP() with the USAC one in the future.


@asmorkalov

Is there somewhere something to have a list of API breaking changes in OpenCV 5?
I think the removal of SOLVEPNP_DLS and SOLVEPNP_UPNP flags should be documented in the doc for instance.

If the change of default values of enum SolvePnPMethod is not an issue, the PR is ready.

@s-trinh s-trinh marked this pull request as ready for review June 22, 2025 19:09
@ivashmak
Copy link
Contributor

I have not encountered these issues, at least not situations where the DLS singularity could have been specifically pinpointed. Main reason is to clean-up the code and avoid issue where someone thinks he is using SOLVEPNP_DLS or SOLVEPNP_UPNP while it is SOLVEPNP_EPNP under the hood and to try to improve the library.

Cleaning up code makes sense. I would leave DLS in USAC, because it can significantly improves noisy models from the P3P algorithm. In the documentation, we can make it clear that USAC has 2 solvers.

Is it this one?

class PnPMinimalSolver6PtsImpl : public PnPMinimalSolver6Pts {

Almost, P6P works in the same way as the non-minimal PnP solver, which is some lines below:

class PnPNonMinimalSolverImpl : public PnPNonMinimalSolver {

It basically, builds a large covariance matrix from all inliers, and finds the least squares solution, a projection matrix, which is decomposed later to R and T. While DLS predicts R and T directly, making it more accurate.

I have experienced with poor accuracy with the P3P solver in cv::solvePnP() and when looking online I have found:

/// Given 3D distances between three points and cosines of 3 angles at the apex, calculates
/// the lengths of the line segments connecting projection center (P) and the three 3D points (A, B, C).
/// Returned distances are for |PA|, |PB|, |PC| respectively.
/// Only the solution to the main branch.
/// Reference : X.S. Gao, X.-R. Hou, J. Tang, H.-F. Chang; "Complete Solution Classification for the Perspective-Three-Point Problem"
/// IEEE Trans. on PAMI, vol. 25, No. 8, August 2003
/// \param lengths Lengths of line segments up to four solutions.
/// \param distances Distance between 3D points in pairs |BC|, |AC|, |AB|.
/// \param cosines Cosine of the angles /_BPC, /_APC, /_APB.
/// \returns Number of solutions.
/// WARNING: NOT ALL THE DEGENERATE CASES ARE IMPLEMENTED

which seem to corroborate with my experiments.

So actually it could be a good idea to replace the P3P in cv::solvePnP() with the USAC one in the future.

I know that my P3P version is faster, I am not sure (do not remember) about accuracy from direct comparison with OpenCV P3P. However, I tested before (around 3 years ago) that USAC PnP (overall) is faster and more accurate than the other OpenCV PnP methods.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
category: calib3d cleanup Code cleanup (e.g, drop legacy C-API, legacy unmaintained code)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy