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_matrix为camera_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_matrix和distCoeffs参数,这是必要的.所以,我修改了它在一个虚拟的饲料camera_matrix和distCoeffs,哎,它的作品!
唯一的区别我可以在我看到之间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_GUESScameraMatrix包含进一步优化的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目录中的示例以补充文档.你应该能解决大多数问题的两件事.)