2013-02-16 73 views
3

我想用OpenCV C++ API执行摄像机标定,使用一组已知的图像点匹配。使用OpenCV进行摄像机标定

OpenCV的一个名为cv::calibrateCamera作为记录here功能。这明确提到,该功能将推导用于平面物体的内部相机矩阵,并且它期望用户 指定用于非平面3D环境的矩阵。

在我的点对应中,世界坐标不是平面的。我对内部摄像头矩阵没有一个合格的猜测。

在这种情况下,我该如何校准相机?

目前,我使用了使用cv::SVD::solveZ函数的计算基于简单的DLT方法。但我想使用OpenCV执行的非线性估计。

+0

如果您有能力在Windows上的单独程序中脱机运行相机跟踪,请查看[ACTS](http://www.zjucvg.net/acts/acts.html)。我遇到了同样的问题,但ACTS在摄像机校准方面做得非常好。很抱歉,我无法帮助您实现OpenCV。 – TaZ 2013-02-16 10:27:12

回答

2

This page解释了如何执行相机自动校准。这包括一种使用Kruppa方程的方法,这种方法似乎可以使用所需的非线性技术解决。

0

我是在同样的情况:我有一个非平面的三维目标,但是我想用的OpenCV的非线性LM-优化校准过程。 (由OpenCV的使用张的初始化方法只允许平面校准目标)

你可以做的是提取从你自己的DLT结果相机矩阵,并以此作为对calibrateCamera初始猜测。如果只为一对完成就足够了(相机点 - 对象点)。尽管其他对可能会生成其他相机矩阵,但它们希望是相似的,您只需要该矩阵即可进行初始化。

请注意,尽管如此,通过您自己的DLT,您可以获得投影矩阵P,该投影矩阵将同类世界点X映射到hom。图像点x通过x = P * X

这将是要走的路,这是蟒蛇虽然,你应该能够适应自己的需要:

P = YOUR_DLT(imagePoints[0], objectPoints[0]) 

cameraMatrix, _, _, _, _, _, _ = cv2.decomposeProjectionMatrix(P) 
cameraMatrix /= cameraMatrix[2,2]   # ensure unit elem[2,2] 
cameraMatrix[0,1] = 0      # ensure no skew 
cameraMatrix[0,0] = abs(cameraMatrix[0,0]) # ensure positive focal lengthes 
cameraMatrix[1,1] = abs(cameraMatrix[1,1]) 

# ensure principal point within image: 
cameraMatrix[0,2] = min(resX-1, max(0, cameraMatrix[0,2])) 
cameraMatrix[1,2] = min(resY-1, max(0, cameraMatrix[1,2])) 

retval, cameraMatrix, distCoeffs, rvecs, tvecs = \ 
     cv2.calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix) 

注意,因为calibrateCamera假设cameraMatrix[2,2]==1和约束为正的焦距和0偏斜,相机矩阵可能需要更正,正如我在上面的代码中所展示的那样。