opencv/modules/calib3d/include/opencv2
s-trinh f5014c179f
Merge pull request #27736 from s-trinh:use_USAC_P3P_in_solvePnP
Update Gao P3P with Ding P3P #27736

### Pull Request Readiness Checklist

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

- [x] I agree to contribute to the project under Apache 2 License.
- [x] 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
- [x] The PR is proposed to the proper branch
- [x] 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

---

The current Gao P3P implementation does not cover all the degenerate cases, **see last line** in: 6d889ee74c/modules/calib3d/src/p3p.cpp (L211-L221)

See also:
- https://github.com/opencv/opencv/issues/4854

---

<details>

<summary>OBSOLETE</summary>

To fix this, the USAC P3P from OpenCV 5 is used instead: 7e6da007cd/modules/3d/src/usac/pnp_solver.cpp (L282)

---

## Some results

### Old P3P vs new

In the following video, I have tried to highlight the viewpoints which cause issues:

https://github.com/user-attachments/assets/97bec6a6-4043-4509-b50e-a9856d6423bd

| | Old P3P    | New P3P |
| -------- | ------- | ------- |
| Mean (ms)  | 0.045701 | 0.024816 |
| Median (ms) | 0.025146 | 0.023193 |
| Std (ms)    | 0.028953    | 0.006124 |

### New P3P vs AP3P

https://github.com/user-attachments/assets/eaeb21dc-3ffd-4b6c-9902-4352f824aa45

The AP3 method is superior both in term of accuracy and computation time:

| | New P3P    | AP3P |
| -------- | ------- | ------- |
| Mean (ms)  | 0.043750 | 0.023442 |
| Median (ms) | 0.023193 | 0.021484 |
| Std (ms)    | 0.039920 | 0.005265 |

### New P3P vs AP3P (range test)

https://github.com/user-attachments/assets/572e7b7a-2966-4bed-8e0c-b93d863987dc

The implemented P3P method does not work well when the tag is small, at long range.

| | New P3P    | AP3P |
| -------- | ------- | ------- |
| Mean (ms)  | 0.031351 | 0.025189 |
| Median (ms) | 0.022217 | 0.020996 |
| Std (ms)    | 0.024920 | 0.009633 |

---

- I have tried to simplify the P3P code, hope I did not break the implementation code
- calculations are performed using double type for simplicity.
- code such as the following are redundant and no more needed and should be replaced by `cv::Rodrigues`:

6d889ee74c/modules/calib3d/src/usac/pnp_solver.cpp (L395)

</details>
2025-10-16 15:21:15 +03:00
..
calib3d mostly removed obsolete C API from calib3d (at least at the interface level) (#13081) 2018-11-09 16:12:22 +03:00
calib3d.hpp Merge pull request #27736 from s-trinh:use_USAC_P3P_in_solvePnP 2025-10-16 15:21:15 +03:00