diff --git a/src/OpenCvSharp/Modules/geometry/Enum/SolvePnPFlags.cs b/src/OpenCvSharp/Modules/geometry/Enum/SolvePnPMethod.cs
similarity index 56%
rename from src/OpenCvSharp/Modules/geometry/Enum/SolvePnPFlags.cs
rename to src/OpenCvSharp/Modules/geometry/Enum/SolvePnPMethod.cs
index 261162399..98073c11d 100644
--- a/src/OpenCvSharp/Modules/geometry/Enum/SolvePnPFlags.cs
+++ b/src/OpenCvSharp/Modules/geometry/Enum/SolvePnPMethod.cs
@@ -27,32 +27,19 @@ public enum SolvePnPMethod
///
P3P = 2,
- ///
- /// **Broken implementation. Using this flag will fallback to EPnP**.
- /// Joel A. Hesch and Stergios I. Roumeliotis. "A Direct Least-Squares (DLS) Method for PnP"
- ///
- DLS = 3,
-
- ///
- /// **Broken implementation. Using this flag will fallback to EPnP.**
- /// Method is based on the paper of A.Penate-Sanchez, J.Andrade-Cetto, F.Moreno-Noguer.
- /// "Exhaustive Linearization for Robust Camera Pose and Focal Length Estimation"
- ///
- UPNP = 4,
-
///
/// Method is based on the paper of T. Ke, S. Roumeliotis
/// "An Efficient Algebraic Solution to the Perspective-Three-Point Problem"
/// In this case the function requires exactly four object and image points.
///
- AP3P = 5,
+ AP3P = 3,
///
/// Method is based on the paper of T. Collins and A. Bartoli.
/// "Infinitesimal Plane-Based Pose Estimation".
/// This method requires coplanar object points.
///
- IPPE = 6,
+ IPPE = 4,
///
/// Method is based on the paper of Toby Collins and Adrien Bartoli.
@@ -63,46 +50,11 @@ public enum SolvePnPMethod
/// - point 2: [squareLength / 2, -squareLength / 2, 0]
/// - point 3: [-squareLength / 2, -squareLength / 2, 0]
///
- IPPE_SQUARE = 7,
+ IPPESquare = 5,
///
/// Method is based on the paper "A Consistently Fast and Globally Optimal Solution to the
/// Perspective-n-Point Problem" by G. Terzakis and M. Lourakis. It requires 3 or more points.
///
- SQPNP = 8,
-}
-
-///
-/// Obsolete: Use SolvePnPMethod instead. This enum is kept for backward compatibility.
-///
-[Obsolete("Use SolvePnPMethod instead", true)]
-public enum SolvePnPFlags
-{
- ///
- /// Iterative method is based on Levenberg-Marquardt optimization.
- /// In this case the function finds such a pose that minimizes reprojection error,
- /// that is the sum of squared distances between the observed projections imagePoints and the projected (using projectPoints() ) objectPoints .
- ///
- Iterative = 0,
-
- ///
- /// Method has been introduced by F.Moreno-Noguer, V.Lepetit and P.Fua in the paper “EPnP: Efficient Perspective-n-Point Camera Pose Estimation”.
- ///
- EPNP = 1,
-
- ///
- /// Method is based on the paper of X.S. Gao, X.-R. Hou, J. Tang, H.-F. Chang“Complete Solution Classification for
- /// the Perspective-Three-Point Problem”. In this case the function requires exactly four object and image points.
- ///
- P3P = 2,
-
- ///
- /// Joel A. Hesch and Stergios I. Roumeliotis. "A Direct Least-Squares (DLS) Method for PnP"
- ///
- DLS = 3,
-
- ///
- /// A.Penate-Sanchez, J.Andrade-Cetto, F.Moreno-Noguer. "Exhaustive Linearization for Robust Camera Pose and Focal Length Estimation"
- ///
- UPNP = 4,
+ SQPNP = 6,
}
diff --git a/test/OpenCvSharp.Tests/calib3d/Calib3dTest.cs b/test/OpenCvSharp.Tests/calib3d/Calib3dTest.cs
index 68a09d27e..bf779ce2b 100644
--- a/test/OpenCvSharp.Tests/calib3d/Calib3dTest.cs
+++ b/test/OpenCvSharp.Tests/calib3d/Calib3dTest.cs
@@ -481,6 +481,79 @@ public void SolvePnPTestByArray(bool useExtrinsicGuess)
Cv2.SolvePnP(objPts, imgPts, cameraMatrix, dist, ref rvec, ref tvec, useExtrinsicGuess: useExtrinsicGuess);
}
+ [Theory]
+ [InlineData(SolvePnPMethod.P3P)]
+ [InlineData(SolvePnPMethod.AP3P)]
+ [InlineData(SolvePnPMethod.IPPE)]
+ [InlineData(SolvePnPMethod.SQPNP)]
+ public void SolvePnPTestByArrayMethods(SolvePnPMethod method)
+ {
+ var rvec = new double[] { 3, 0, 0 };
+ var tvec = new double[] { 0, 0, 10 };
+ var cameraMatrix = new double[,]
+ {
+ { 1, 0, 0 },
+ { 0, 1, 0 },
+ { 0, 0, 1 }
+ };
+ var dist = new double[] { 0, 0, 0, 0, 0 };
+
+ var objPts = new[]
+ {
+ new Point3f(0,0,1),
+ new Point3f(1,0,1),
+ new Point3f(0,1,1),
+ new Point3f(1,1,1)
+ };
+
+ Cv2.ProjectPoints(objPts, rvec, tvec, cameraMatrix, dist, out var imgPts, out _);
+
+ Cv2.SolvePnP(objPts, imgPts, cameraMatrix, dist, ref rvec, ref tvec, flags: method);
+
+ // Verify the recovered pose actually reprojects onto imgPts (rather than just "didn't throw"):
+ // a stale/misdirected enum value can silently dispatch to a different native solver that
+ // still runs to completion without throwing, but produces a wrong pose.
+ Cv2.ProjectPoints(objPts, rvec, tvec, cameraMatrix, dist, out var reprojected, out _);
+ for (var i = 0; i < imgPts.Length; i++)
+ {
+ Assert.Equal(imgPts[i].X, reprojected[i].X, 3);
+ Assert.Equal(imgPts[i].Y, reprojected[i].Y, 3);
+ }
+ }
+
+ [Fact]
+ public void SolvePnPTestByArrayIPPESquare()
+ {
+ var rvec = new double[] { 3, 0, 0 };
+ var tvec = new double[] { 0, 0, 10 };
+ var cameraMatrix = new double[,]
+ {
+ { 1, 0, 0 },
+ { 0, 1, 0 },
+ { 0, 0, 1 }
+ };
+ var dist = new double[] { 0, 0, 0, 0, 0 };
+
+ var objPts = new[]
+ {
+ new Point3f(-0.5f, 0.5f, 0),
+ new Point3f(0.5f, 0.5f, 0),
+ new Point3f(0.5f, -0.5f, 0),
+ new Point3f(-0.5f, -0.5f, 0)
+ };
+
+ Cv2.ProjectPoints(objPts, rvec, tvec, cameraMatrix, dist, out var imgPts, out _);
+
+ Cv2.SolvePnP(objPts, imgPts, cameraMatrix, dist, ref rvec, ref tvec, flags: SolvePnPMethod.IPPESquare);
+
+ Cv2.ProjectPoints(objPts, rvec, tvec, cameraMatrix, dist, out var reprojected, out _);
+ for (var i = 0; i < imgPts.Length; i++)
+ {
+ Assert.Equal(imgPts[i].X, reprojected[i].X, 3);
+ Assert.Equal(imgPts[i].Y, reprojected[i].Y, 3);
+ }
+ }
+
[Fact]
public void SolvePnPTestByMat()
{