Reputation: 1161
I'm trying to run camera calibration using opencv in python. I'm using:
cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None)
and it seems like it is working well for 5 distortion coefficients. However, I would like to try and run it without the tangential distortion and possibly with only 2 radial distortion coefficients. Is that possible?
Upvotes: 1
Views: 4567
Reputation: 1805
distCoeffs – Output vector of distortion coefficients
of 4, 5, or 8 elements.
CV_CALIB_USE_INTRINSIC_GUESS cameraMatrix contains valid initial values of fx, fy, cx, cy that are optimized further. Otherwise, (cx, cy) is initially set to the image center ( imageSize is used), and focal distances are computed in a least-squares fashion. Note, that if intrinsic parameters are known, there is no need to use this function just to estimate extrinsic parameters. Use solvePnP() instead.
CV_CALIB_FIX_K1,...,CV_CALIB_FIX_K6 The corresponding radial distortion coefficient is not changed during the optimization. If CV_CALIB_USE_INTRINSIC_GUESS is set, the coefficient from the supplied distCoeffs matrix is used. Otherwise, it is set to 0.
CV_CALIB_ZERO_TANGENT_DIST Tangential distortion coefficients
are set to zeros and stay zero.
IMPORTANT: in Python, cv flags DON'T BEGIN WITH CV_
. So I will remove them from now on.
What the documentation means is:
If you already have a camera matrix AND distortion coefficient vector, you can supply them to the calibration as an initial value and let it guess from there (using CALIB_USE_INTRINSIC_GUESS
). You can supply an initial distortion vector and make some components of it static (will always be the supplied value) with the CALIB_FIX_K1
,…,CALIB_FIX_K6
flags.
BUT: if you set CALIB_FIX_K1
, CALIB_FIX_K2
, CALIB_FIX_K3
, CALIB_FIX_K4
, CALIB_FIX_K5
or CALIB_FIX_K6
without giving an initial estimate, they will be set to zero.
Note that the result distCoeffs vector will be: [K1
, K2
, tangential1
, tangential2
, K3
]. OpenCV will give you K4, K5 or K6 only if you explicitly ask for it with CALIB_RATIONAL_MODEL
.
So, if you want no tangential distortion factors and only two radial distortion factors, you can supply flags=CALIB_FIX_K3 + CALIB_ZERO_TANGENT_DIST
. You don't need distCoeffs
or just pass it as distCoeffs=None
.
success, mtx, distCoeffs, rvecs, tvecs = cv2.calibrateCamera(
objectPoints, imagePoints, (width, height),
flags=CALIB_FIX_K3 + CALIB_ZERO_TANGENT_DIST)
print(distCoeffs)
This will result in a distortion vector like this:
[ 0.10509459 -0.31389323 0. 0. 0. ]
Upvotes: 2
Reputation: 1161
I found the answer.
For no tangential distortion:
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None, 4,None,None,cv2.CALIB_ZERO_TANGENT_DIST,
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 2e-16))
For only 2 radial distortion coefficients it seems like the documentation suggests using 4 instead of 5 for the number of coefficients. That does not seem to work. Instead I fix the k3 parameter:
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None, 4,None,None,cv2.CALIB_ZERO_TANGENT_DIST+cv2.CALIB_FIX_K3,
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 2e-16))
Upvotes: 2