我想使用OpenCV C++API执行相机校准,使用一组已知的世界到图像点匹配。
OpenCV有一个名为cv::calibrateCamera
的函数,如本文所述。这清楚地提到,函数将推导平面物体的固有相机矩阵及其对用户的期望以指定非平面3D环境的矩阵。
在我的点对应中,世界坐标不是平面的。我对内部摄像头矩阵没有一个合格的猜测。
在这种情况下,我该如何校准相机?
目前,我正在使用一种简单的基于DLT的方法来使用cv::SVD::solveZ
函数进行计算。但我想使用OpenCV执行的非线性估计。
本页介绍如何执行相机自动校准。这包括一种使用Kruppa方程的方法,该方程似乎可以使用您想要的非线性技术来求解。
我也处于同样的情况:我有一个非平面的3D目标,但我想在校准过程中使用OpenCV的非线性LM优化。(OpenCV使用的张初始化方法只允许平面校准目标)
您可以做的是从自己的DLT结果中提取相机矩阵,并将其用作calibrateCamera
的初始猜测。如果只对一对(相机点-对象点)进行操作就足够了。尽管其他对可能会产生其他相机矩阵,但它们有望相似,而且无论如何,您只需要该矩阵进行初始化。
不过,请注意,我确实假设,使用您自己的DLT,您可以获得投影矩阵P
,该矩阵将齐次世界点X
映射到hom。图像点CCD_ 6经由CCD_。
这将是一条路,不过在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偏斜,因此可能需要校正相机矩阵,正如我在上面的代码中所示。