Search code examples
pythonopencvnumpyopencv3.0opencv-solvepnp

OpenCV Error: Assertion failed in undistort.cpp at line 293


Found solution at https://github.com/opencv/opencv/issues/4943

OpenCV Error:

Assertion failed (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 cvUndistortPoints, file /home/javvaji/opencv-3.2.0/modules/imgproc/src/undistort.cpp, line 293

retval, rvec, tvec = cv2.solvePnP(cam.object_points, cam.image_points, cam.camera_matrix, cam.dist_coefficients, None, None, False, cv2.SOLVEPNP_P3P)

I am using solvePnP function with flag SOLVEPNP_P3P. It is giving assertion error. The same solvePnP code works fine with SOLVEPNP_ITERATIVE flag. With P3P flag it internally calls undistortPoints function which is giving error.

solvePnP code ref

How to resolve this?


Solution

  • Incomplete docs -- solvePnP in python (Problem is known, an issue is open in the opencv github repository)

    • Numpy array slices won't work as input because solvePnP requires contiguous arrays (enforced by the assertion using cv::Mat::checkVector() around line 55 of modules/calib3d/src/solvepnp.cpp version 2.4.9)

    • The P3P algorithm requires image points to be in an array of shape (N,1,2) since it's calling cv::undistortPoints (around line 75 of modules/calib3d/src/solvepnp.cpp version 2.4.9) which requires 2-channel information.

    • Thus, given some data D = np.array(...) where D.shape = (N,M), in order to use a subset of it as, e.g., imagePoints, one must effectively copy it into a new array: imagePoints = np.ascontiguousarray(D[:,:2]).reshape((N,1,2))