1

Goodmorning everyone!

I am struggling with the opencv function calibrateCamera where I retrieve the following error:

OpenCV(4.5.4) D:\a\opencv-python\opencv-python\opencv\modules\calib3d\src\calibration.cpp:3350: error: (-210:Unsupported format or combination of formats) objectPoints should contain vector of vectors of points of type Point3f in function 'cv::collectCalibrationData'

I tried to find a solution, but could not find anything anywhere except for type issues or length issues. I use a np.array of float 32 type for both objPoints and imgPoints:


    objpoints = np.array(objpoints, dtype = np.float32)
    imgpoints = np.array(imgpoints, dtype = np.float32)
    ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, imsize, None, None )

The Variable Explorer gives the following values for the used variables:


    In: objpoints
    Out: 
    array([[  0. , 246.5,   0. ],
           [ 14.5, 246.5,   0. ],
           [ 43.5, 246.5,   0. ],
           ...,
           [174. ,   0. ,   0. ],
           [319. ,   0. ,   0. ],
           [333.5,   0. ,   0. ]], dtype=float32)
    
    In: imgpoints
    Out: 
    array([[1310., 1032.],
           [1258., 1032.],
           [1154., 1032.],
           [1206., 1032.],
           ...,
           [ 739.,  134.],
           [ 686.,  133.],
           [ 162.,  132.],
           [ 110.,  132.]], dtype=float32)
    
    In: imsize
    Out: (1080, 1440)
    
    In: len(imgpoints)
    Out: 440
    In: len(objpoints)
    Out: 440

I also tried switching objpoints and imgpoints in the calibrateCamera function, but that resulted in the same error message. As I read a lot of solutions for this function in C++ I want to point out that this is a Python related question.

I hope someone can help me with this! Thanks in advance!

Matt
  • 31
  • 6

3 Answers3

3

This function can take multiple views (let's say N), each possibly showing a different object.

"vector of vector of points" means each "vector of points" is allowed to have a different length, because maybe that object is different from the objects seen in other views.

You can pass a single array with outer dimension (N, ...), if all your views show the same object (the arrays have the same length), but you should pass a list of arrays in the general case, so each array can have its own suitable size.

objApoints = np.array(objApoints, dtype=np.float32)
img1points = np.array(img1points, dtype=np.float32)

# have another picture? img2points...
# it may show the same object (objApoints) or a different object (objBpoints)

objpointslist = [objApoints]
imgpointslist = [img1points]

cv2.calibrateCamera(objpointslist, imgpointslist, ...)
Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
  • Thanks for your comment! I did as you suggested with my 4 calibration images and now it is working! Great to see the support from the community! – Matt Dec 17 '21 at 10:33
2

ImagePoints and objectPoints should contain vector of vectors of points. This means that you should have image and object points for multiple images.In your case I see there is image and object points for just one image. What you can do is to use np.newaxis in this case as follows. However to make the calibration do better, try to have multiple images.

objpoints = np.array(objpoints, dtype = np.float32)[np.newaxis]
imgpoints = np.array(imgpoints, dtype = np.float32)[np.newaxis]
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, imsize, None, None )
Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
cyborg
  • 554
  • 2
  • 7
  • that's valid only if all objects have the same number of points – Christoph Rackwitz Dec 17 '21 at 10:12
  • Thanks for pointing out about having multiple images. I was thinking about it myself how to include the other images as well. Now I changed it according to the suggestion of Christoph Rackwitz as mentioned above. – Matt Dec 17 '21 at 10:32
0

SOLVED: I had to put the objpoints and imgpoints inside a list before I made a numpy array from them:

objpoints = np.array([objpoints], dtype = np.float32)
imgpoints = np.array([imgpoints], dtype = np.float32)

Instead of:

objpoints = np.array(objpoints, dtype = np.float32)
imgpoints = np.array(imgpoints, dtype = np.float32)
Matt
  • 31
  • 6