diff --git a/modules/calib3d/misc/python/test/test_solvepnp.py b/modules/calib3d/misc/python/test/test_solvepnp.py index b751e15c742a020b657b445cd5f57af9f26aa3b8..f7765c0384cf92828fabad6516588d76d0f07caa 100644 --- a/modules/calib3d/misc/python/test/test_solvepnp.py +++ b/modules/calib3d/misc/python/test/test_solvepnp.py @@ -39,6 +39,26 @@ class solvepnp_test(NewOpenCVTests): obj_points, img_points, cameraMatrix, distCoeffs, reprojectionError=r ) + def test_regression_16049(self): + obj_points = np.array([[0, 0, 0], [0, 1, 0], [1, 1, 0], [1, 0, 0]], dtype=np.float32) + img_points = np.array( + [[[700, 400], [700, 600], [900, 600], [900, 400]]], dtype=np.float32 + ) + + cameraMatrix = np.array( + [[712.0634, 0, 800], [0, 712.540, 500], [0, 0, 1]], dtype=np.float32 + ) + distCoeffs = np.array([[0, 0, 0, 0]], dtype=np.float32) + x, r, t, e = cv.solvePnPGeneric( + obj_points, img_points, cameraMatrix, distCoeffs + ) + if e is None: + # noArray() is supported, see https://github.com/opencv/opencv/issues/16049 + pass + else: + eDump = cv.utils.dumpInputArray(e) + self.assertEqual(eDump, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=1 dims(-1)=2 size(-1)=1x1 type(-1)=CV_32FC1") + if __name__ == '__main__': NewOpenCVTests.bootstrap() diff --git a/modules/calib3d/src/solvepnp.cpp b/modules/calib3d/src/solvepnp.cpp index d2fb3976c5cb8083fcc4f63a796e701682f4a461..0fcd670abcd6f119357bcbe949a3988a5bcccd3f 100644 --- a/modules/calib3d/src/solvepnp.cpp +++ b/modules/calib3d/src/solvepnp.cpp @@ -1009,7 +1009,10 @@ int solvePnPGeneric( InputArray _opoints, InputArray _ipoints, if (reprojectionError.needed()) { - int type = reprojectionError.type(); + int type = (reprojectionError.fixedType() || !reprojectionError.empty()) + ? reprojectionError.type() + : (max(_ipoints.depth(), _opoints.depth()) == CV_64F ? CV_64F : CV_32F); + reprojectionError.create(solutions, 1, type); CV_CheckType(reprojectionError.type(), type == CV_32FC1 || type == CV_64FC1, "Type of reprojectionError must be CV_32FC1 or CV_64FC1!");