2

I am new to Python, OpenCV, and Numpy. I have been attempting to implement a python version of C++ code which determines the relative pose of a camera to a known marker. The code uses the cv2.SolvePnP function, which I have been at wits end to get to run. I have searched the web, but find nothing but similar confusion for this function. It seems that no matter what form I pass my data, the function is unhappy. The test case I've been using is:

## target image points

tPoints = np.zeros((4,2),dtype=np.float64)
tPoints[0,0] = 384.3331
tPoints[0,1] = 162.23618
tPoints[1,0] = 385.27521
tPoints[1,1] = 135.21503
tPoints[2,0] = 409.36746
tPoints[2,1] = 165.64435

## actual marker point set

mPoints = np.zeros((4,3),dtype=np.float64)
mPoints[0,0] = -88.0
mPoints[0,1] = 88.0
mPoints[0,2] = 0
mPoints[1,0] = -88.0
mPoints[1,1] = -88.0
mPoints[1,2] = 0
mPoints[2,0] = 88.0
mPoints[2,1] = -88.0
mPoints[2,2] = 0
mPoints[3,0] = 88.0
mPoints[3,1] = 88.0
mPoints[3,2] = 0

camMatrix = np.zeros((3,3),dtype=np.float64 )
camMatrix[0][0] = 519.0
camMatrix[0][2] = 320.0
camMatrix[1][1] = 522.0
camMatrix[1][2] = 240.0
camMatrix[2][2] = 1.0

retval, rvec, tvec = cv2.solvePnP(objectPoints = tPoints, imagePoints = mPoints, cameraMatrix = camMatrix, distCoeffs = None)

The error returned is:

cv2.error: C:\slave\WinInstallerMegaPack\src\opencv\modules\calib3d\src\solvepnp.cpp:52: >error: (-215) npoints >= 0 && npoints == std::max(ipoints.checkVector(2, CV_32F), >ipoints.checkVector(2, CV_64F))

Help getting this to execute, as well as information as to where I am going wrong will be greatly appreciated. Lots still to learn!

user2039916
  • 21
  • 1
  • 3

2 Answers2

3

The shapes of the arguments that you've given to solvePnP are not correct. objectPoints should be Nx3, and imagePoints should be Nx2. If I switch how tPoints and mPoints are assigned to these arguments in your example, it does not raise the exception.

Warren Weckesser
  • 110,654
  • 19
  • 194
  • 214
  • Thanks! I seem to have gotten confused in what are "objectPoints" and what are "imagePoints". I really appreciate the quick help! – user2039916 Feb 04 '13 at 17:35
  • I am still having problems. When I change the two arrays the exception goes away, but is replaced by a different error, "ValueError: need more than 2 values to unpack". I assume I am formatting the array(s) incorrectly, but I'm still at a loss. Any help appreciated. – user2039916 Feb 04 '13 at 19:15
  • Think I found the problem. The OpenCV 4.3.2 documentation states that the function call returns three values: "Python: cv2.solvePnP(objectPoints, imagePoints, cameraMatrix, distCoeffs[, rvec[, tvec[, useExtrinsicGuess[, flags]]]]) → retval, rvec, tvec". It appears that only rvec and tvec are actually being returned, since everything seems to work fine without the third variable ('retval') being specified. Not sure the array values are correct, but at least I have something that seems to work. Thanks for looking at my problem. – user2039916 Feb 04 '13 at 20:45
  • (I think you mean 2.4.3.) Strange. I'm using 2.4.2, and your code worked for me (after adding the appropriate imports and swapping the objectPoints and imagePoints arguments). I wouldn't expect a point release to make such a fundamental API change. – Warren Weckesser Feb 04 '13 at 21:05
  • Yes, 2.4.3, my mind is getting tired. I tracked the issue further and it is my 'bad', as this particular laptop is actually an older version of openCV, not 2.4.3 which my work machine is using....I thought I had updated both, obviously I did not. But, still, thanks for pointing out the array problem, as that really solves the problem! – user2039916 Feb 04 '13 at 22:04
3

If you try to slice an array as input this will also cause problems. Taken from here

World = array([[-0.5, -0.5,  3. ],
               [ 0.5, -0.5,  3. ],
               [ 0.5,  0.5,  3. ],
               [-0.5,  0. ,  3. ]])
keyPoints = array([[ 279.03286469,  139.80463604,    1.        ],
                     [ 465.40665724,  136.70519839,    1.        ],
                     [ 465.40665724,  325.1505936 ,    1.        ],
                     [ 279.03286469,  230.927896  ,    1.        ]])

objectPoints = World
imagePoints = keyPoints[:,:2] # <--- THIS SLICE IS A PROBLEM CAUSER!!!
cv2.solvePnP(objectPoints, imagePoints, np.eye(3), np.zeros(5))
Ben
  • 953
  • 8
  • 20