Key Engineering Takeaways
- •The Intrinsic Matrix K maps 3D camera coordinates to 2D image pixels via focal lengths (fx, fy) and optical center (cx, cy).
- •Wide-angle lenses exhibit barrel distortion; calibrating with OpenCV undistorts images for accurate geometric SLAM and vision guidance.
- •Always capture at least 15-20 chessboard images at varying angles and depths filling the entire camera field of view.
Prerequisites
- • Matrix algebra
- • Python OpenCV
Required Hardware / Tools
- • USB Webcam / Raspberry Pi Camera
- • Printed 8x6 Checkerboard Calibration Target
The Pinhole Camera Model & Intrinsic Matrix K
A camera projects a 3D point $\mathbf{P}_c = [X_c, Y_c, Z_c]^T$ in the camera coordinate frame onto a 2D pixel coordinate $\mathbf{p} = [u, v]^T$:
$$\begin{bmatrix} u \\ v \\ 1 \end{bmatrix} \sim \mathbf{K} \begin{bmatrix} X_c / Z_c \\ Y_c / Z_c \\ 1 \end{bmatrix} = \begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} X_c / Z_c \\ Y_c / Z_c \\ 1 \end{bmatrix}$$
Automated OpenCV Chessboard Calibration Script
Here is the complete Python calibration script:
calibrate_camera.py
python
import cv2
import numpy as np
import glob
# Checkerboard dimensions (inner corners)
CHECKERBOARD = (9, 6)
SQUARE_SIZE_MM = 25.0 # 25mm per square
# 3D world coordinates of checkerboard corners
objp = np.zeros((CHECKERBOARD[0] * CHECKERBOARD[1], 3), np.float32)
objp[:, :2] = np.mgrid[0:CHECKERBOARD[0], 0:CHECKERBOARD[1]].T.reshape(-1, 2) * SQUARE_SIZE_MM
objpoints = [] # 3D real world points
imgpoints = [] # 2D pixel points
images = glob.glob('calibration_images/*.jpg')
for fname in images:
img = cv2.imread(fname)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, corners = cv2.findChessboardCorners(gray, CHECKERBOARD, None)
if ret:
objpoints.append(objp)
# Refine corner sub-pixel precision
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)
imgpoints.append(corners2)
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(
objpoints, imgpoints, gray.shape[::-1], None, None
)
print("=== CAMERA CALIBRATION RESULTS ===")
print(f"Reprojection Error (RMS): {ret:.4f} pixels")
print("Intrinsic Matrix K:
", mtx)
print("Distortion Coefficients [k1, k2, p1, p2, k3]:
", dist.ravel())Tags:#Computer Vision#OpenCV#Camera Calibration#Pinhole Model#Distortion#Python