In this tutorial, we will demonstrate how to calibrate a camera using OpenCV (computer vision open-source library). Here we apply some of the concepts from our introductory tutorial about computer vision.
The main objective of this post is to present the steps necessary to prepare the camera’s calibration. The need for calibration of the visual sensor (camera) is relevant when we want to use the captured frames for computer vision applications/tasks. Standard Python code examples are presented in this tutorial.
In order to illustrate how to carry out the calibration process, the equipment described below was used in this tutorial, however the calibration process can be done with similar hardware.
- Print an A4 paper with the calibration chessboard;
- Hardware – Webcam Logitech BRIO 4K Ultra HD RightLight™ 3 HDR, Lenovo ideapad 530s-14ikb (with a processor – Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz 1.99GHz and a installation Windows 10 Enterprise, 10.0.19041 Build 190);
- Software – IDE Visual Studio Code with the plugin for Python (Python 3.8.5).
In addition to the requirements described above, it is necessary to install the OpenCV open-source library, which contains several computer vision algorithms. To install this library you must type in a Command Prompt “pip install opencv-python”, “pip install opencv-python-contrib”, “pip install numpy”and then “pip install glob2”.
Camera Calibration Steps
The calibration process should follow the following steps:
- Capture several images of the calibration chessboard from different angles of view;
- Find the 2D coordinates of the calibration chessboard;
- Calibrate the camera;
- Undistortion camera.
Below will be described the details of each step.
Capture several images (calibration chessboard) from different views
Through calibration chessboard (Figure 1), the standard method for camera calibration, we will capture several images using the camera we want to calibrate from various perspectives. We should capture at least 10 images.
Note: we can capture these images in two distinct ways, fixing the calibration chessboard and changing the position and orientation or the reverse by fixing the camera and changing the position and orientation of the calibration chessboard. For the presented tutorial, it is irrelevant how the images are captured, either one form or the other.
Find the 2D coordinates (calibration chessboard)
In the code below, we can see after the comment “# termination criteria” these criteria come from the fact of using the “cornerSubPix” function (in the paragraph described below). Then, in the variable “objp” a matrix is created with the size of our chessboard, in this case 6 (height) by 7 (width), making this our reference (virtual map) as the chessboard should be in reality.
import numpy as np import glob # termination criteria criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30, 0.001) # prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0) objp = np.zeros((6*7,3), np.float32) objp[:,:2] = np.mgrid[0:7,0:6].T.reshape(-1,2) # Arrays to store object points and image points from all the images. objpoints =  # 3d point in real world space imgpoints =  # 2d points in image plane. images = glob.glob('*.jpg') for fname in images: img = cv.imread(fname) gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) # Find the chess board corners ret, corners = cv.findChessboardCorners(gray, (7,6), None) # If found, add object points, image points (after refining them) if ret == True: objpoints.append(objp) corners2 = cv.cornerSubPix(gray,corners, (11,11), (-1,-1), criteria) imgpoints.append(corners) # Draw and display the corners cv.drawChessboardCorners(img, (7,6), corners2, ret) cv.imshow('img', img) cv.waitKey(500) cv.destroyAllWindows()
With the various images captured from the calibration chessboard, we were able to obtain the 2D pixel location of the corners of the calibration chessboard. For that we must create a directory with all the images (images = glob.glob(‘directory name’)), then through the “findChessboardCorners” function, it is possible to find the corners inside the chessboard.
To improve the original detection, the “cornerSubPix” function is used, its main purpose is to find a better location for each of the detected corners, according to the original neighbourhood. Since this function is iterative, it is necessary to specify the closing criteria, defining the number of iterations to perform and the precision we want to obtain. This process is done in the captured image (Figure 2).
Calibrate the camera
With the code presented above, we were able to obtain the camera matrix, as well as its coefficients, for that just use the code shown below. We can save these values in a .csv file (for example) to later use in the calibration of this camera in particular or use them straight away to undistortion the camera directly, thus removing the distortion of the image.
ret, mtx, dist, rvecs, tvecs = cv.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
To carry out the undistortion, as mentioned above, just use the appropriate parameters, using the “undistort” function:
dst = cv.undistort (img, mtx, dist, None, newcameramtx)
In the example used throughout this tutorial it is not easily noticeable the removal of the distortion of the camera, so I leave here an image that has distortion, so you can see the difference. Additionally, it is possible to verify and evaluate the reprojection error, thus being possible to estimate how accurate the estimate of the parameters of our algorithm is, thus understanding how robust our calibration is.