Calibrating a Camera with OpenCV

I want to calibrate a camera using the OpenCV C ++ API using a set of known matches between worlds and images.

OpenCV has a feature cv::calibrateCamera

as described here . This clearly indicates that the function will output the built-in camera matrix for planar objects and that it expects the user to specify the matrix for non-planar 3D environments.

In my correspondence points, the world coordinates are not flat. And I don't have a qualified guess for the camera's internal matrix.

How would I do camera calibration in this case?

I am currently using a simple DLT based method to compute with a function cv::SVD::solveZ

. But I would like to use the non-linear estimation that OpenCV does.

+3


source to share


2 answers


This page explains how to calibrate the camera automatically. This includes a method using the Kruppa equations, which appear to be solvable using the non-linear methods you desire.



+2


source


I was in the same situation: I have a non-planar 3D target, however I wanted to use OpenCV's non-linear LM optimization for the calibration process. (The Zhang initialization method used by OpenCV only allows planetary targets)

What you can do is extract the camera matrix from your own DLT result and use that as an initial guess for calibrateCamera

. Enough if done for one pair, only (camera points - object points). While other pairs may create different camera matrices, they will hopefully be similar and you only need this matrix for initialization.

Note, I believe that with your own DLT, you get a projection matrix P

that maps the homogeneous points of the world X

to hom. image points X

through x = P * X

.



This will be the way to go, but in python you should be able to adapt to your own needs:

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) 

      

Note, since it calibrateCamera

accepts cameraMatrix[2,2]==1

and is limited to positive focal lengths and 0 skews, it might be necessary to adjust the camera matrix as I showed in the code above.

0


source







All Articles