AI Hints
Home›Computer Vision Tutorial›Geometry in Practice
Computer Vision · Lesson 58 of 111

Calibrating a Camera

Turning a camera into a measuring tool.

⏱ 2 min read▶ Video at 1:32:41🎓 Free
Watch this lesson in the Computer Vision courseWatch on YouTube ↗Full Computer Vision course

Every lens bends light slightly, and straight lines curve near the edges. If you want to measure in millimetres, you need to know exactly how your lens behaves. There's an elegant way to find out. Photograph a checkerboard.

Calibrating a Camera
From the video: Calibrating a Camera
  • Every lens bends light
  • Straight lines curve
  • Photograph a checkerboard

Calibration

A checkerboard has corners at exact, known positions. Here we simulate twelve photos of a board, using a known camera, and known distortion, with a little noise. In real life, you'd detect the corners in real photos. Then calibrate camera solves for everything at once. Run it. Reprojection error tells you how well the model explains the photos, and anything under about half a pixel is good. It's point two one. The focal length came back as eight hundred and one, and the truth was eight hundred. And the distortion matches too. From a dozen photos, we've worked out the inner workings of the camera.

calibrate.pypython
import cv2
import numpy as np

board = np.zeros((6 * 9, 3), np.float32)
board[:, :2] = np.mgrid[0:9, 0:6].T.reshape(-1, 2) * 25.0
K = np.array([[800, 0, 320], [0, 800, 240], [0, 0, 1]], float)
dist = np.array([-0.25, 0.1, 0, 0, 0], float)
rng = np.random.default_rng(0)

views_3d, views_2d = [], []
for i in range(12):
    rvec = rng.uniform(-0.4, 0.4, 3)
    tvec = np.array([rng.uniform(-80, -40), rng.uniform(-70, -30), rng.uniform(350, 500)])
    pts, _ = cv2.projectPoints(board, rvec, tvec, K, dist)
    views_3d.append(board)
    views_2d.append((pts + rng.normal(0, 0.15, pts.shape)).astype(np.float32))

err, K2, d2, _, _ = cv2.calibrateCamera(views_3d, views_2d, (640, 480), None, None)
print(f"Reprojection error: {err:.2f} pixels")
print(f"Focal length: {K2[0, 0]:.0f} (true 800)")
print(f"Distortion k1: {d2[0, 0]:.2f} (true -0.25)")
Output
Reprojection error: 0.21 pixels
Focal length: 801 (true 800)
Distortion k1: -0.25 (true -0.25)

Doing it for real

Use fifteen to twenty photos, with the board at different angles, and covering the corners of the frame. Keep the board perfectly flat. Lock the focus and zoom, because changing either one means calibrating again. Then undistort every frame before measuring. And recheck it regularly, as a knock can shift a lens.

15-20 photosmany angles
Cover the cornersdistortion lives there
Lock focus and zoomor recalibrate
Recheckknocks shift lenses

Summary

Calibration turns a camera into a measuring device. Next, let's bring in time. Moving objects.

Key takeaways
  • Checkerboards have known corners
  • Reprojection error scores the fit
  • Lock the focus
Next up: Separating Moving Things — background subtraction