A complete implementation of camera calibration using a checkerboard pattern, implemented entirely from scratch using NumPy, OpenCV, and SciPy. This project demonstrates the mathematical foundations of camera calibration without relying on OpenCV's built-in calibration functions.
- Overview
- Features
- Algorithm
- Requirements
- Installation
- Usage
- Results
- Technical Details
- Project Structure
- License
AutoCalib performs camera intrinsic calibration by:
- Detecting checkerboard corners in multiple calibration images
- Computing homographies between the checkerboard plane and image plane
- Estimating the camera intrinsic matrix using Zhang's method
- Extracting rotation and translation matrices for each view
- Optimizing camera parameters using Levenberg-Marquardt optimization
- Visualizing reprojection accuracy on undistorted images
The calibration process estimates:
- Camera Intrinsic Matrix (K): Focal lengths, principal point, and skew
- Distortion Coefficients (kβ, kβ): Radial distortion parameters
- Extrinsic Parameters: Rotation and translation for each calibration image
- β Pure NumPy Implementation: Core algorithms implemented from scratch
- β Zhang's Calibration Method: Industry-standard calibration algorithm
- β Non-linear Optimization: Levenberg-Marquardt optimization for parameter refinement
- β Radial Distortion Correction: Models and corrects lens distortion
- β Visual Validation: Generates images showing reprojected points
- β Sub-pixel Corner Detection: Uses OpenCV's cornerSubPix for accurate corner detection
The calibration process follows these steps:
- Detects checkerboard corners using
cv2.findChessboardCorners - Refines corners to sub-pixel accuracy using
cv2.cornerSubPix - Creates 3D object points from the known checkerboard dimensions
- Computes homography matrices between the checkerboard plane and each image
- Uses SVD (Singular Value Decomposition) to solve the homography equations
- Each homography relates the 3D checkerboard coordinates to 2D image coordinates
- Applies Zhang's method using the constraints from multiple homographies
- Solves a system of equations derived from the orthogonality constraints
- Estimates initial values for focal lengths (Ξ±, Ξ²), principal point (uβ, vβ), and skew (Ξ³)
- Decomposes each homography to extract rotation and translation
- Ensures orthonormality of rotation vectors
- Computes the third rotation vector using cross product
- Optimizes camera parameters using
scipy.optimize.least_squares - Minimizes reprojection error across all calibration images
- Refines intrinsic parameters and distortion coefficients
- Projects 3D points back to image space using optimized parameters
- Applies radial distortion correction
- Visualizes reprojected points on undistorted images
- Python 3.6+
- NumPy
- OpenCV (cv2)
- SciPy
# Clone the repository
git clone <repository-url>
cd AutoCalib
# Install dependencies
pip install numpy opencv-python scipy-
Prepare Calibration Images: Place your checkerboard calibration images in the
Calibration_Imgs/directory. The images should show the checkerboard from different angles and positions. -
Configure Parameters: Edit
Wrapper.pyto set:rows: Number of inner corners in the checkerboard (rows)cols: Number of inner corners in the checkerboard (columns)square_size: Physical size of each square in millimeters
rows = 9 # Inner corners: 9 rows cols = 6 # Inner corners: 6 columns square_size = 21.5 # Size in mm
-
Run Calibration:
python Wrapper.py
-
View Results:
- Calibration parameters are printed to the console
- Reprojected images are saved in the
Results/directory - Red circles indicate where the checkerboard corners should be after calibration
The calibration process outputs:
Average error before optimization: <initial_error>
Final K: [[fx, s, cx], [0, fy, cy], [0, 0, 1]]
Final k: [k1, k2]
Average error after optimization: <final_error>
The script generates images showing the reprojected points (red circles) overlaid on the undistorted calibration images:
Reprojected corners on undistorted image 0
Reprojected corners on undistorted image 5
Reprojected corners on undistorted image 1
The red circles indicate where the checkerboard corners are projected based on the calibrated camera model. Smaller reprojection errors indicate better calibration accuracy.
The pinhole camera model with radial distortion is used:
Projection:
[u] [fx s cx] [X]
[v] = [0 fy cy] [Y]
[1] [0 0 1] [Z]
Radial Distortion:
x_distorted = x * (1 + kβrΒ² + kβrβ΄)
y_distorted = y * (1 + kβrΒ² + kβrβ΄)
where rΒ² = xΒ² + yΒ²
get_corners(): Detects and refines checkerboard cornersfind_Homography(): Computes homography using SVDget_camera_matrix(): Estimates initial camera intrinsics using Zhang's methodget_R_t(): Extracts rotation and translation from homographiesget_projected_points(): Projects 3D points to 2D with distortionget_geometric_error(): Objective function for optimization
The project includes 13 calibration images showing a checkerboard pattern from various viewpoints:
Example calibration image with checkerboard pattern
AutoCalib/
β
βββ Wrapper.py # Main calibration script
βββ Calibration_Imgs/ # Input calibration images
β βββ IMG_20170209_042606.jpg
β βββ IMG_20170209_042608.jpg
β βββ ...
βββ Results/ # Output images with reprojected points
β βββ Reprojected_0.jpg
β βββ Reprojected_1.jpg
β βββ ...
βββ checkerboardPattern.pdf # Checkerboard pattern reference
βββ LICENSE # License file
βββ README.md # This file
This implementation is particularly useful for:
- Understanding the mathematical foundations of camera calibration
- Learning Zhang's calibration method
- Seeing how optimization improves calibration accuracy
- Visualizing the effects of distortion correction
See the LICENSE file for details.
- Based on Zhang's camera calibration method (1999)
- Uses OpenCV for corner detection and image processing
- SciPy for non-linear optimization
Note: This is a from-scratch implementation for educational purposes. For production use, consider using OpenCV's cv2.calibrateCamera() which includes additional optimizations and robustness features.