Skip to content

Fix SolvePnPMethod enum values to match native OpenCV5 numbering - #2081

Merged
shimat merged 3 commits into
mainfrom
fix/solvepnp-method-enum-values-2080
Jul 23, 2026
Merged

shimat merged 3 commits into
mainfrom
fix/solvepnp-method-enum-values-2080

Conversation

@shimat

@shimat shimat commented Jul 23, 2026 •

Copy link
Copy Markdown
Owner

Description

Cv2.SolvePnP / Cv2.SolvePnPRansac pass SolvePnPMethod straight through as a native int flags value, but the enum's numeric values were never updated when the geometry module dropped SOLVEPNP_DLS and SOLVEPNP_UPNP (both were broken implementations that only fell back to EPnP) and renumbered the remaining SOLVEPNP_* constants:

Iterative EPNP P3P AP3P IPPE IPPE_SQUARE SQPNP
native (current) 0 1 2 3 4 5 6
managed (before) 0 1 2 5 6 7 8

This meant AP3P/IPPE silently invoked the wrong native algorithm, and IPPE_SQUARE/SQPNP fell outside the native flag range and threw StsBadArg.

Changes

  • Renumber SolvePnPMethod (AP3P=3, IPPE=4, IPPE_SQUARE=5, SQPNP=6) to match the native enum, and drop the now-nonexistent DLS/UPNP members.
  • Remove the obsolete SolvePnPFlags alias enum (kept around from the OpenCvSharp4 days) since OpenCvSharp5 doesn't guarantee source compatibility with the old API. Renamed the containing file to SolvePnPMethod.cs to match its sole remaining type.
  • Add regression tests in Calib3dTest covering P3P/AP3P/IPPE/SQPNP/IPPE_SQUARE.

Fixes #2080

Test plan

  • dotnet build succeeds
  • dotnet test --filter FullyQualifiedName~calib3d — 90 passed, 0 failed

Summary by CodeRabbit

  • Breaking Changes

    • Removed unsupported SolvePnPMethod options DLS and UPNP.
    • Updated numeric values for the remaining SolvePnPMethod members.
    • Renamed IPPE_SQUARE to IPPESquare.
  • Tests

    • Added additional SolvePnP test cases that validate accuracy across multiple SolvePnPMethod values.
    • Added a dedicated test covering SolvePnPMethod.IPPESquare.

The geometry module removed the broken DLS/UPnP methods (both just
fell back to EPnP) and renumbered the remaining SOLVEPNP_* constants,
but the managed SolvePnPMethod enum still carried the old OpenCV4
values. As a result AP3P/IPPE silently ran the wrong native algorithm,
and IPPE_SQUARE/SQPNP were rejected outright since they fell outside
the native flag range.

Also drops the obsolete SolvePnPFlags alias enum, which is no longer
needed now that OpenCvSharp5 doesn't guarantee source compatibility
with the 4.x API.

Fixes #2080
@shimat shimat self-assigned this Jul 23, 2026
@coderabbitai

coderabbitai Bot commented Jul 23, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: de0c2f8c-bb8f-47be-b235-ba881a8ca9d2

📥 Commits

Reviewing files that changed from the base of the PR and between 6945bd0 and c4a86d2.

📒 Files selected for processing (2)
  • src/OpenCvSharp/Modules/geometry/Enum/SolvePnPMethod.cs
  • test/OpenCvSharp.Tests/calib3d/Calib3dTest.cs
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/OpenCvSharp/Modules/geometry/Enum/SolvePnPMethod.cs
  • test/OpenCvSharp.Tests/calib3d/Calib3dTest.cs

📝 Walkthrough

Walkthrough

SolvePnPMethod removes DLS and UPNP, renumbers the remaining values, and renames IPPE_SQUARE to IPPESquare. New calibration tests exercise multiple methods and the square variant with synthetic projected points.

Changes

SolvePnP method alignment

Layer / File(s) Summary
Renumber SolvePnP methods
src/OpenCvSharp/Modules/geometry/Enum/SolvePnPMethod.cs
Removes DLS and UPNP, renumbers the remaining methods, and renames IPPE_SQUARE to IPPESquare.
Validate SolvePnP methods
test/OpenCvSharp.Tests/calib3d/Calib3dTest.cs
Adds theory and fact coverage that projects synthetic points and calls Cv2.SolvePnP with multiple methods, including IPPESquare.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly states the main change: fixing SolvePnPMethod enum values to match OpenCV5 numbering.
Linked Issues check ✅ Passed The enum renumbering and regression tests address the reported SolvePnP rejection for SQPNP and IPPE_Square.
Out of Scope Changes check ✅ Passed The changes stay focused on SolvePnPMethod numbering and regression coverage, with no clear unrelated additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/solvepnp-method-enum-values-2080

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/OpenCvSharp/Modules/geometry/Enum/SolvePnPMethod.cs (1)

53-53: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use PascalCase for the compound enum member.

IPPE_SQUARE is not a standalone acronym. Rename it to the repository’s PascalCase form, such as IppeSquare, and update callers in test/OpenCvSharp.Tests/calib3d/Calib3dTest.cs.

Suggested rename
-    IPPE_SQUARE = 5,
+    IppeSquare = 5,

As per coding guidelines, C# enum members from C++ ALL_CAPS_WITH_UNDERSCORES should use PascalCase for compounds, except standalone acronyms.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/OpenCvSharp/Modules/geometry/Enum/SolvePnPMethod.cs` at line 53, Rename
the SolvePnPMethod enum member IPPE_SQUARE to IppeSquare, then update all
references in Calib3dTest.cs and any other callers to use the new PascalCase
identifier.

Source: Coding guidelines

test/OpenCvSharp.Tests/calib3d/Calib3dTest.cs (1)

484-512: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Assert the recovered pose, not only that the call does not throw.

Because Cv2.SolvePnP forwards (int)flags directly, these tests can pass while dispatching to another valid solver. Reproject with the returned rvec/tvec and assert low error; also add explicit integer assertions for the renumbered members.

Suggested validation
         Cv2.SolvePnP(objPts, imgPts, cameraMatrix, dist, ref rvec, ref tvec, flags: method);
+        Cv2.ProjectPoints(objPts, rvec, tvec, cameraMatrix, dist, out var reproj, out _);
+        Assert.Equal(imgPts.Length, reproj.Length);
+        for (var i = 0; i < imgPts.Length; i++)
+        {
+            Assert.InRange(MathF.Abs(reproj[i].X - imgPts[i].X), 0f, 1e-3f);
+            Assert.InRange(MathF.Abs(reproj[i].Y - imgPts[i].Y), 0f, 1e-3f);
+        }

Also applies to: 514-538

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/OpenCvSharp.Tests/calib3d/Calib3dTest.cs` around lines 484 - 512,
Strengthen SolvePnPTestByArrayMethods and the corresponding test around the
later overload to validate the returned pose: reproject objPts using the updated
rvec and tvec, then assert the reprojection error is below a small tolerance
against imgPts. Add explicit assertions for the integer values of each
renumbered SolvePnPMethod member so flags dispatch to the intended solver.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/OpenCvSharp.Tests/calib3d/Calib3dTest.cs`:
- Around line 491-492: Update the synthetic camera poses in the projection tests
around the rvec/tvec setup to use a positive Z translation, changing each
affected tvec from [0, 0, -10] to [0, 0, 10] while preserving the other pose
values.

---

Nitpick comments:
In `@src/OpenCvSharp/Modules/geometry/Enum/SolvePnPMethod.cs`:
- Line 53: Rename the SolvePnPMethod enum member IPPE_SQUARE to IppeSquare, then
update all references in Calib3dTest.cs and any other callers to use the new
PascalCase identifier.

In `@test/OpenCvSharp.Tests/calib3d/Calib3dTest.cs`:
- Around line 484-512: Strengthen SolvePnPTestByArrayMethods and the
corresponding test around the later overload to validate the returned pose:
reproject objPts using the updated rvec and tvec, then assert the reprojection
error is below a small tolerance against imgPts. Add explicit assertions for the
integer values of each renumbered SolvePnPMethod member so flags dispatch to the
intended solver.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 97499327-c3c1-4b4a-b1a8-d12f6bd92eca

📥 Commits

Reviewing files that changed from the base of the PR and between 5d08d9c and e44ae11.

📒 Files selected for processing (2)
  • src/OpenCvSharp/Modules/geometry/Enum/SolvePnPMethod.cs
  • test/OpenCvSharp.Tests/calib3d/Calib3dTest.cs

Comment thread test/OpenCvSharp.Tests/calib3d/Calib3dTest.cs Outdated
shimat added 2 commits July 23, 2026 13:12
- Rename SolvePnPMethod.IPPE_SQUARE to IppeSquare: once an acronym is
  glued to another word to form a compound member name, this repo's
  enum-naming convention PascalCases the whole compound rather than
  leaving part of it in caps (see .github/copilot-instructions.md).
- Use a positive-Z tvec in the new synthetic poses so the projected
  points sit in front of the camera instead of behind it.
- Strengthen SolvePnPTestByArrayMethods/IppeSquare to reproject with
  the recovered pose and assert it matches the input points, instead
  of only asserting the call doesn't throw. Confirmed this actually
  matters: with the old AP3P/IPPE values, SolvePnP silently dispatches
  to a different native solver that still completes without throwing,
  so a throws-only assertion doesn't catch it - the reprojection check
  does.
CodeRabbit's suggested PascalCase compound (IppeSquare) follows the
letter of the naming convention doc, but AKAZEDescriptorType already
has an established precedent for this exact shape (acronym + plain
word) that keeps the acronym in caps: KAZEUpright/MLDBUpright, not
KazeUpright/MldbUpright. Match that existing style instead so IPPE
(the bare enum member) and the compound built from it stay visually
related.
@shimat
shimat merged commit 52fa2c5 into main Jul 23, 2026
15 checks passed
@shimat
shimat deleted the fix/solvepnp-method-enum-values-2080 branch July 23, 2026 05:13
@shimat shimat added the bug Confirmed defect in OpenCvSharp label Jul 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Confirmed defect in OpenCvSharp

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SolvePnP fails with IPPE_SQUARE and SQPNP in OpenCvSharp5

1 participant