using matlab
The latest version of MATLAB (2014) has a built-in Camera Calibrator. You can learn to use it here. You feed it about a dozen images of a checkerboard, and it will automatically determine the camera’s distortion. Sounds great, but it couldn’t detect the corners in most of my images from an underwater camera. It didn't work.
UPDATE (21 APRIL 2015): The MATLAB Computer Vision System Toolbox team has been very proactive in addressing this issue. It's worth trying their system again.
This worked: The Camera Calibration Toolbox for MATLAB, downloaded here. It requires you to manually click corners of the checkerboard in your images; it sounds tedious but it’s not really. Your results will look something like:
Focal Length: fc = [ 1755.04324 1754.95349 ] ± [ 22.44731 20.56242 ]
Principal point: cc = [ 650.63208 545.93890 ] ± [ 18.33014 16.47342 ]
Skew: alpha_c = [ 0.00000 ] ± [ 0.00000 ] => angle of pixel axes = 90.00000 ± 0.00000 degrees
Distortion: kc = [ 0.16858 0.57600 0.01030 -0.01824 0.00000 ] ± [ 0.03928 0.30327 0.00512 0.00548 0.00000 ]
Pixel error: err = [ 0.66638 0.47196 ]
The toolbox lets you undistort one image at a time. I used openCV to undistort a batch of 20,000 images by running the script below and plugging in the above parameters. That said, there’s probably a way to do this in MATLAB with a for loop and the undistortImage function.
import numpy as np
import cv2
import glob
# copy parameters to arrays
K = np.array([[1755.04324, 0., 650.63], [0, 1754.95349, 545.9389],[0, 0, 1]])
d = np.array([.16858, 0.57600, 0, 0, 0]) # just use first two terms
images = glob.glob('/Users/Grace/pythontest/imgs/nui004_proc_origionals/*.tif')
for fname in images:
# read image
img = cv2.imread(fname)
h, w = img.shape[:2]
# undistort
newcamera, roi = cv2.getOptimalNewCameraMatrix(K, d, (w,h), 0)
newimg = cv2.undistort(img, K, d, None, newcamera)
# save image
newfname = fname+'.undis.tif'
cv2.imwrite(newfname, newimg)
UPDATE (21 APRIL 2015): The MATLAB Computer Vision System Toolbox team has been very proactive in addressing this issue. It's worth trying their system again.
This worked: The Camera Calibration Toolbox for MATLAB, downloaded here. It requires you to manually click corners of the checkerboard in your images; it sounds tedious but it’s not really. Your results will look something like:
Focal Length: fc = [ 1755.04324 1754.95349 ] ± [ 22.44731 20.56242 ]
Principal point: cc = [ 650.63208 545.93890 ] ± [ 18.33014 16.47342 ]
Skew: alpha_c = [ 0.00000 ] ± [ 0.00000 ] => angle of pixel axes = 90.00000 ± 0.00000 degrees
Distortion: kc = [ 0.16858 0.57600 0.01030 -0.01824 0.00000 ] ± [ 0.03928 0.30327 0.00512 0.00548 0.00000 ]
Pixel error: err = [ 0.66638 0.47196 ]
The toolbox lets you undistort one image at a time. I used openCV to undistort a batch of 20,000 images by running the script below and plugging in the above parameters. That said, there’s probably a way to do this in MATLAB with a for loop and the undistortImage function.
import numpy as np
import cv2
import glob
# copy parameters to arrays
K = np.array([[1755.04324, 0., 650.63], [0, 1754.95349, 545.9389],[0, 0, 1]])
d = np.array([.16858, 0.57600, 0, 0, 0]) # just use first two terms
images = glob.glob('/Users/Grace/pythontest/imgs/nui004_proc_origionals/*.tif')
for fname in images:
# read image
img = cv2.imread(fname)
h, w = img.shape[:2]
# undistort
newcamera, roi = cv2.getOptimalNewCameraMatrix(K, d, (w,h), 0)
newimg = cv2.undistort(img, K, d, None, newcamera)
# save image
newfname = fname+'.undis.tif'
cv2.imwrite(newfname, newimg)
Using opencv
You can also, theoretically, do the whole calibration in openCV. It didn’t work for me though because openCV wasn’t able to detect the checkerboard corners in most of my images. In any event, the instructions are here on Solem’s vision blog, where most of the code above is from. I found his method easier than the one on the openCV python tutorial. You'll find the calibrate.py function you need in opencv/samples/python2. One note is that Solem says to use
$ python calibrate.py “calibration_samples/GOPR00*.JPG"
But this only worked for me without the quotes, and with a tilde; e.g.,
$ python calibrate.py ~/pythontest/left0*.jpg
$ python calibrate.py “calibration_samples/GOPR00*.JPG"
But this only worked for me without the quotes, and with a tilde; e.g.,
$ python calibrate.py ~/pythontest/left0*.jpg