使用OpenCV进行摄像机校准

时间:2013-02-16 10:20:03

标签: c++ opencv computer-vision

我想使用OpenCV C ++ API执行相机校准,使用一组已知世界来进行图像点匹配。

OpenCV有一个名为cv::calibrateCamera的函数,记录为here。这明确提到该功能将推断出 平面物体的内在相机矩阵,它需要用户 为非平面3D环境指定矩阵。

在我的点对应中,世界坐标不是平面的。而且我对内部相机矩阵没有合格的猜测。

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

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

2 个答案:

答案 0 :(得分:2)

This page说明了如何执行相机自动校准。这包括使用Kruppa方程的方法,该方程似乎可以使用您想要的非线性技术解决。

答案 1 :(得分:0)

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

您可以做的是从您自己的DLT结果中提取相机矩阵,并将其用作calibrateCamera的初始猜测。仅对一对进行就足够了(相机点 - 对象点)。即使其他对可能产生其他相机矩阵,它们也可能是相似的,并且您只需要初始化就可以使用该矩阵。

注意,我确实假设,使用您自己的DLT,您可以获得一个投影矩阵P,它将齐次世界点X映射到hom。图像点x通过x = P * X

这将是要走的路,但是在python中,你应该能够适应自己的需求:

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偏斜,因此我可能需要更正相机矩阵,正如我在上面的代码中所示。