python cv2.calibrateCamera抛出错误:objectPoints应包含Point3f类型的矢量向量

时间:2018-03-04 20:43:14

标签: python opencv

我有代码

img = cv2.imread("poolPictures\chessboard3.jpg", cv2.IMREAD_COLOR)
chessboardImage = cv2.imread("poolPictures\chessboardActual.jpg", cv2.IMREAD_COLOR)

ret, corners = cv2.findChessboardCorners(img, (9,6), None)
cv2.drawChessboardCorners(img, (9,6), corners, ret)

chessRet, chessCorners = cv2.findChessboardCorners(chessboardImage, (9,6), None)
ret, matrix, dist, rvecs, tvecs = cv2.calibrateCamera(corners, chessCorners, chessboardImage.shape[::-1][1:3], None, None)`

运行代码会引发错误:

ret, matrix, dist, rvecs, tvecs = cv2.calibrateCamera(corners, chessCorners, chessboardImage.shape[::-1][1:3], None, None) cv2.error: C:\projects\opencv-python\opencv\modules\calib3d\src\calibration.cpp:3110: error: (-210) objectPoints should contain vector of vectors of points of type Point3f in function cv::collectCalibrationData

chessboard3.jpg:

chessboard3.jpg

chessboardActual.jpg:

chessboardActual.jpg

绘制棋盘的结果:

results of draw chessboard

我尝试通过引入虚拟的第三维将对象点转换为3维向量而不是2 - 我找不到Point3f()的python版本。

我也从这里看到https://github.com/opencv/opencv/issues/6002有时错误可能会产生误导,真正的问题是imagePoints中的一个向量是空的 - 我已经尝试打印向量而没有一个是空的。

希望有人可以提供帮助,可能只是拍摄更多照片......

干杯,

3 个答案:

答案 0 :(得分:1)

正如Zenith042指出的那样,我的图像点和对象点的方向是错误的。然而,主要的问题是,而不是像我的图像点的numpy数组:

[[[ 137.5  205. ]]
[[ 143.5  206.5]]
 .
 .
 .
[[ 137.5  209.5]]]

我需要:

[[ 137.5 205. ]
[ 143.5 206.5]
.
.
.
[ 137.5 209.5]]]

我所取得的成就:

ret, corners = cv2.findChessboardCorners(img, (9,6), None)
corners = np.array([[corner for [corner] in corners]])

虽然我怀疑numpy.reshape有一个更好的方法。

我还需要对象点的相同结构,即

objp = np.array([objp])

答案 1 :(得分:0)

您可以使用

创建虚拟objPoints
>>> objp = np.zeros((6*9, 3), np.float32)
>>> objp[:,:2] = np.mgrid[0:9, 0:6].T.reshape(-1,2)
>>> objp
array([[ 0.,  0.,  0.],
   [ 1.,  0.,  0.],
   [ 2.,  0.,  0.],
   [ 3.,  0.,  0.],
   [ 4.,  0.,  0.],
   [ 5.,  0.,  0.],
   [ 6.,  0.,  0.],
   [ 7.,  0.,  0.],
   [ 8.,  0.,  0.],
   [ 0.,  1.,  0.],
   [ 1.,  1.,  0.],
   [ 2.,  1.,  0.],
   [ 3.,  1.,  0.],
   [ 4.,  1.,  0.],
   [ 5.,  1.,  0.],
   [ 6.,  1.,  0.],
   [ 7.,  1.,  0.],
   [ 8.,  1.,  0.],
   [ 0.,  2.,  0.],
   [ 1.,  2.,  0.],
   [ 2.,  2.,  0.],
   [ 3.,  2.,  0.],
   [ 4.,  2.,  0.],
   [ 5.,  2.,  0.],
   [ 6.,  2.,  0.],
   [ 7.,  2.,  0.],
   [ 8.,  2.,  0.],
   [ 0.,  3.,  0.],
   [ 1.,  3.,  0.],
   [ 2.,  3.,  0.],
   [ 3.,  3.,  0.],
   [ 4.,  3.,  0.],
   [ 5.,  3.,  0.],
   [ 6.,  3.,  0.],
   [ 7.,  3.,  0.],
   [ 8.,  3.,  0.],
   [ 0.,  4.,  0.],
   [ 1.,  4.,  0.],
   [ 2.,  4.,  0.],
   [ 3.,  4.,  0.],
   [ 4.,  4.,  0.],
   [ 5.,  4.,  0.],
   [ 6.,  4.,  0.],
   [ 7.,  4.,  0.],
   [ 8.,  4.,  0.],
   [ 0.,  5.,  0.],
   [ 1.,  5.,  0.],
   [ 2.,  5.,  0.],
   [ 3.,  5.,  0.],
   [ 4.,  5.,  0.],
   [ 5.,  5.,  0.],
   [ 6.,  5.,  0.],
   [ 7.,  5.,  0.],
   [ 8.,  5.,  0.]], dtype=float32)

然后你可以打电话

ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objp, corners, img.shape[::-1],None,None)

您无需为calibrateCamera提供“实际”棋盘图像。

答案 2 :(得分:0)

根据this问题,OpenCV还要求浮点数具有单精度。

这意味着每个数组在传递给np.float32之前都需要转换为calibrateCamera