3

I need to use the CV_P3P solvePnP method, but there doesn't seem to be any documentation of the python equivalents of the C++ flags, which are CV_ITERATIVE, CV_P3P and CV_EPNP. I've tried cv2.CV_P3P, cv2.P3P, cv2.cv.P3P, etc.

I've found a few questions asking this, including these:

http://opencv-users.1802565.n2.nabble.com/solvePNP-name-of-flag-constants-in-Python-td7484093.html

http://answers.opencv.org/question/8861/what-opencv-constants-are-available/

But no answers, apart from a link to this source page, which defines python constants. But there seem to be no references to the constants I'm looking for. https://github.com/Itseez/opencv/blob/e3ae36dcb3c1d523802f8642e5c3984db43637c4/modules/python/src2/defs

I also tried just passing integers for that argument, but it still seems to be using the default method.

Is it possible the other solve methods don't exist in the python version of opencv?

John
  • 565
  • 1
  • 5
  • 14

2 Answers2

14

I found that the following constants worked:

cv2.SOLVEPNP_ITERATIVE

cv2.SOLVEPNP_P3P

cv2.SOLVEPNP_EPNP

cv2.SOLVEPNP_DLS

E.g:

retval, orvec, otvec = cv2.solvePnP(object_points, image_points, 
            camera_matrix, None, None, None, False, cv2.SOLVEPNP_ITERATIVE)
Ivan
  • 168
  • 1
  • 6
  • 1
    It's worked to me. I'd like to know where this is documented. – David Clifte Jun 22 '17 at 19:47
  • Hi David, I do not think this piece of information was documented. I discovered it by accident when I tried passing different arguments into the function which threw the following error: OpenCV Error: Bad argument (The flags argument must be one of SOLVEPNP_ITERATIVE, SOLVEPNP_P3P, SOLVEPNP_EPNP or SOLVEPNP_DLS) – Ivan Jun 24 '17 at 14:38
  • For whatever reason, my version of `cv2` (`cv2.__version__ == '2.4.9.1'`) does not have that flag; however, it does have `CV_EPNP`. Found this by dumping `sorted(dir(cv2))` to a file and searching it. – Eric Cousineau May 02 '18 at 20:11
  • 1
    An additional `cv2.SOLVEPNP_UPNP` flag is available in opencv3x. – ndrplz Oct 03 '18 at 07:06
2

Using Python 2.7 and OpenCV 2.4.8 (from apt-get), the flag you have above, "cv2.CV_P3P" works.

Well, I still get an error, but it is managing to call the P3P method. That method then fails with an error (pasted below).

I think it's failing on an assertion that imagePoints is a two-channel, one-dimensional matrix, rather than an Nx2 matrix. This isn't the only place the Python bindings have troubles: solvePnP only accepts Nx3 matrices for objectPoints, failing on 3xN. I believe that this means that the P3P and EPNP methods can't be called from Python, but I'd love to be shown otherwise.

Here's the error:

cv2.error: /build/buildd/opencv-2.4.8+dfsg1/modules/imgproc/src/undistort.cpp:279: error: (-215) CV_IS_MAT(_src) && CV_IS_MAT(_dst) && (_src->rows == 1 || _src->cols == 1) && (_dst->rows == 1 || _dst->cols == 1) && _src->cols + _src->rows - 1 == _dst->rows + _dst->cols - 1 && (CV_MAT_TYPE(_src->type) == CV_32FC2 || CV_MAT_TYPE(_src->type) == CV_64FC2) && (CV_MAT_TYPE(_dst->type) == CV_32FC2 || CV_MAT_TYPE(_dst->type) == CV_64FC2) in function cvUndistortPoints

Tom Allen
  • 21
  • 2
  • Thanks for this! Will call this the answer. Not exactly settled, but certainly shed some light for me :) – John Mar 17 '16 at 14:44
  • I was facing the same error. [This](https://stackoverflow.com/questions/44042323/opencv-error-assertion-failed-in-undistort-cpp-at-line-293) solved my issue (in case link breaks: array contiguity for input matrices is required, which can be enforced using `numpy.ascontiguousarray()`) – ndrplz Oct 03 '18 at 07:10