不使用 cv2.findChessboardCorners 在 Python 中校准 OpenCV 相机

Posted

技术标签:

【中文标题】不使用 cv2.findChessboardCorners 在 Python 中校准 OpenCV 相机【英文标题】:OpenCV camera calibration in Python without using cv2.findChessboardCorners 【发布时间】:2015-10-26 16:08:16 【问题描述】:

我正在尝试使用 openCV 进行相机校准。只要我使用 cv2.findChessBoardCorners 在图像中找到我的校准目标,我就没有问题,但是如果我使用自己的函数来查找点并用这些点构建一个数组,我会在尝试估计相机参数。这是一个会引发相同错误的示例。

import numpy as np
import cv2


pattern_size         = (4, 3)
pattern_points       = np.zeros( (np.prod(pattern_size), 3), np.float32 )
pattern_points[:,:2] = np.indices(pattern_size).T.reshape(-1, 2)
pattern_points      *= 20

obj_points = []
img_points = []

for fn in range(5):
    corners = np.asarray(pattern_points[:,1:], dtype=np.float32)

    img_points.append(corners.reshape(-1, 2))
    obj_points.append(pattern_points)


ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(obj_points,
                                                   img_points,
                                                   (1088, 2048),
                                                   None,
                                                   None)

如果我用通常的方式制作圆角数组

ret, corners = cv2.findChessboardCorners(gray, (4,3))

它工作正常。在这两种情况下,角的类型都是 ndarray 大小 (12,2),元素是 float32。

为什么会出现这个错误:

OpenCV Error: Unsupported format or combination of formats (imagePoints1 should contain vector of vectors of points of type Point2f) in cv::collectCalibrationData, file C:\builds\master_PackSlaveAddon-win32-vc12-static\opencv\modules\calib3d\src\calibration.cpp, line 2982

当我尝试从头开始构造 img_points 数组而不是使用 cv2.findChessboardCorners 时?

【问题讨论】:

请给minimal reproducible example。尝试运行您的代码(除其他外): cv2.error: /home/openstack/opencv/opencv/opencv-3.0.0/modules/calib3d/src/calibration.cpp:2982: error: (-210) imagePoints1 应该包含函数collectCalibrationData中Point2f类型点的向量向量 谢谢。是的,我粘贴了错误的错误。我会马上改正的!虽然问题描述是正确的,并且代码重现了错误,所以如果您能给我任何指示,那就太好了。 我也遇到了同样的问题。如文档所述,我通过使用向量向量来解决它;对于每一帧,imPts = [ [px0, py0, pz0],..., [pxn, pyn, pzn] ] 和 obPts = [ [qx0, qy0],..., [qxn, qyn] ],然后执行: imPts.astype('float32'), obPts.astype('float32') 在函数内部使用它们时。如果使用多于一帧,则对每一帧执行此操作。希望能解决问题 好的。这样可行。谢谢。我对示例进行了以下更改: img_points.append(corners.reshape(-1, 2).astype('float32')) obj_points.append(pattern_points.astype('float32')) 因为我已经转换为 float32我很惊讶它有所作为。 我们可以认为这已经解决了吗? 【参考方案1】:

我也遇到了同样的问题。如文档所述,我通过使用向量向量来解决它;对于每一帧, imPts = [ [px0, py0, pz0],..., [pxn, pyn, pzn] ] obPts = [ [qx0, qy0],..., [qxn, qyn] ],然后执行:imPts.astype('float32')obPts.astype('float32'),在函数内部使用它们时。如果使用多于一帧,则对每一帧执行此操作。这样就行了。

【讨论】:

以上是关于不使用 cv2.findChessboardCorners 在 Python 中校准 OpenCV 相机的主要内容,如果未能解决你的问题,请参考以下文章

c语言报错不允许使用不完整类型,让用户自定义数组大小。

参数标志,不使用时为空,不使用时为默认值

如何设置相机视图旋转(不使用不推荐使用的代码)

使用 jQuery 提交表单并使用 PHP 发送.. 不知道为啥它不发送

UITableViewCell 不使用不推荐使用的方法 initWithFrame:reuseIdentifier

不推荐使用:不推荐使用 FCM 直接通道,请使用 APNs 进行下游消息处理