OpenCV 2.3摄像头校准

hok*_*ird 5 matlab opencv vision computer-vision camera-calibration

我正在尝试使用OpenCV 2.3python绑定来校准相机.我在matlab中使用了下面的数据并且校准工作正常,但我似乎无法在OpenCV中使用它.我作为初始猜测设置的相机矩阵非常接近从matlab工具箱计算的答案.

import cv2
import numpy as np

obj_points = [[-9.7,3.0,4.5],[-11.1,0.5,3.1],[-8.5,0.9,2.4],[-5.8,4.4,2.7],[-4.8,1.5,0.2],[-6.7,-1.6,-0.4],[-8.7,-3.3,-0.6],[-4.3,-1.2,-2.4],[-12.4,-2.3,0.9],    [-14.1,-3.8,-0.6],[-18.9,2.9,2.9],[-14.6,2.3,4.6],[-16.0,0.8,3.0],[-18.9,-0.1,0.3],    [-16.3,-1.7,0.5],[-18.6,-2.7,-2.2]]
img_points = [[993.0,623.0],[942.0,705.0],[1023.0,720.0],[1116.0,645.0],[1136.0,764.0],[1071.0,847.0],[1003.0,885.0],[1142.0,887.0],[886.0,816.0],[827.0,883.0],[710.0,636.0],[837.0,621.0],[789.0,688.0],[699.0,759.0],[768.0,800.0],[697.0,873.0]]

obj_points = np.array(obj_points)
img_points = np.array(img_points)

w = 1680
h = 1050
size = (w,h)

camera_matrix = np.zeros((3, 3))
camera_matrix[0,0]= 2200.0
camera_matrix[1,1]= 2200.0
camera_matrix[2,2]=1.0
camera_matrix[2,0]=750.0
camera_matrix[2,1]=750.0 

dist_coefs = np.zeros(4)
results = cv2.calibrateCamera(obj_points, img_points,size, 
    camera_matrix, dist_coefs)
Run Code Online (Sandbox Code Playgroud)

mat*_*fee 20

首先,你的相机矩阵是错误的.如果您阅读文档,它应该如下所示:

fx  0 cx
 0 fy cy
 0  0  1
Run Code Online (Sandbox Code Playgroud)

如果你看看你的,你的方法是错误的:

fx  0  0
 0 fy  0
cx cy  1
Run Code Online (Sandbox Code Playgroud)

首先,设置camera_matrixcamera_matrix.T(或改变你的构造方式camera_matrix.记住这camera_matrix[i,j] i, j).

camera_matrix = camera_matrix.T
Run Code Online (Sandbox Code Playgroud)

接下来,我运行你的代码,我发现"似乎无法让它工作"意味着以下错误(顺便说一下 - 总是说出你的意思"似乎无法让你的工作"在你的问题中 - 如果是错误,请发布错误.如果它运行但给你怪人号码,请说明:

OpenCV Error: Assertion failed (ni >= 0) in collectCalibrationData, file /home/cha66i/Downloads/OpenCV-2.3.1/modules/calib3d/src/calibration.cpp, line 3161
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
cv2.error: /home/cha66i/Downloads/OpenCV-2.3.1/modules/calib3d/src/calibration.cpp:3161: error: (-215) ni >= 0 in function collectCalibrationData
Run Code Online (Sandbox Code Playgroud)

然后,我阅读了文档(顺便说一下非常有用)并注意到obj_points并且img_points必须是向量的向量,因为可以为同一棋盘的多个图像(/校准点)提供一组对象/图像点.

因此:

cv2.calibrateCamera([obj_points], [img_points],size, camera_matrix, dist_coefs)
Run Code Online (Sandbox Code Playgroud)

什么?我仍然得到同样的错误?!

然后,我看了一下OpenCV python2样本(在文件夹中OpenCV-2.x.x/samples/python2),并注意到一个calibration.py向我展示如何使用校准函数(永远不要低估样本,它们通常比文档更好!).

我试图运行,calibration.py但它没有运行,因为它不提供camera_matrixdistCoeffs参数,这是必要的.所以,我修改了它在一个虚拟的饲料camera_matrixdistCoeffs,哎,它的作品!

唯一的区别我可以在我看到之间obj_points/ img_points和他们,是他们有dtype=float32,而我没有.

所以,我改变我的obj_points并且img_points也有dtype float32(OpenCV的python2接口很有趣;当矩阵没有a时,通常函数不起作用dtype):

obj_points = obj_points.astype('float32')
img_points = img_points.astype('float32')
Run Code Online (Sandbox Code Playgroud)

然后我再试一次:

>>> cv2.calibrateCamera([obj_points], [img_points],size, camera_matrix, dist_coefs)
OpenCV Error: Bad argument 
(For non-planar calibration rigs the initial intrinsic matrix must be specified) 
in cvCalibrateCamera2, file ....
Run Code Online (Sandbox Code Playgroud)

什么?!至少有一个不同的错误.但我确实提供了一个初始内在矩阵!

所以我回到文档,注意flags参数:

flags - 可能为零的不同标志或以下值的组合:

CV_CALIB_USE_INTRINSIC_GUESS cameraMatrix包含进一步优化的fx,fy,cx,cy的有效初始值

...

啊哈,所以我必须明确告诉函数使用我提供的初始猜测:

cv2.calibrateCamera([obj_points], [img_points],size, camera_matrix.T, dist_coefs,
                    flags=cv2.CALIB_USE_INTRINSIC_GUESS)
Run Code Online (Sandbox Code Playgroud)

欢呼!有用!

(故事的道德 - 如果您正在使用Python cv2界面,请仔细阅读OpenCV文档,并使用最新版本(即在opencv.itseez.com上).另外,请参阅samples/python2目录中的示例以补充文档.你应该能解决大多数问题的两件事.)