3DCV Workshop 01 - Webcam Calibration with OpenCV¶
Workshop Overview¶
In this workshop, you will learn how to calibrate a webcam using OpenCV. This involves four key steps:
- Capturing images of a chessboard pattern.
- Computing and storing calibration parameters using those images.
- Applying the calibration to correct distortion in the webcam feed.
- Rendering a 3D coordinate system into the image.
Hints¶
- This tutorial is based on the OpenCV tutorial on Camera Calibration. If you are stuck with a task, you can check the solution from the tutorial.
- It make sense to write one Python file for each step.
Preparation¶
- We are using Python 3.12 or later. Install from python.org
- It is recommended to use Visual Studio Code for development, but you can also use any other suitable IDE.
- Take care that Python is properly installed by checking the version in your command line tool:
python --version
- Create a virtual environment so that the needed modules are only used for this project:
python -m venv .venv
- Activate the virtual environment before installing the modules:
# For Windows use
.venv\Scripts\Activate.ps1
# For Linux and Mac OS
source .venv/bin/activate
- Note for Windows: If activation fails, please consult the link in the error message (something about PowerShell ExecutionPolicy) or the following guide for more information. When the environment is activated, you should see this as a prefix on your terminal.
- Install OpenCV Python with
pip install opencv-python
. Note that this tutorial was tested with versionopencv-python-4.11.0.86
- Connect the webcam to your computer.
- Check if everything is set up correctly by running this Python script:
import cv2
# Connect to the webcam
id = 0
cap = cv2.VideoCapture(id)
if not cap.isOpened():
print("Error: Could not open webcam.")
exit()
# Create a window to display the webcam feed
cv2.namedWindow("Webcam")
# Main loop to capture images
while True:
ret, frame = cap.read()
if not ret:
print("Error: Failed to capture image.")
break
# Show the webcam feed
cv2.imshow("Webcam", frame)
# Handle key presses
key = cv2.waitKey(10)
match key:
case 113: # ord('q') = 113 (quit)
break
# Release resources
cap.release()
cv2.destroyAllWindows()
Error handling¶
Error: Could not open webcam.
might appear if theid
is wrong or the camera is not properly connected.Error: Failed to capture image.
might appear if the camera is broken. Try another one.
Step 1: Capturing Images for Calibration¶
Before calibrating a camera, we need multiple images of a chessboard pattern taken from different angles. These images help OpenCV determine how the camera distorts the view.
Task¶
Extend the given Python script so that it:
- Captures an image when the user presses the
's'
key. - Saves the images in a folder (
captured_images
). - Allows deleting all existing images with the
'd'
key.
Hints¶
- Use
cv2.imwrite()
to save images. - Use
cv2.waitKey()
to detect key presses. -
If you are not able to capture any images, you can use the example images from OpenCV: left01.jpg ... left14.jpg.
-
Challenge: Modify the script to show all saved images in a grid format.
Step 2: Calibrating the Camera¶
Now that we have images of a chessboard, we need to compute the camera's intrinsic parameters (like focal length and distortion coefficients).
How It Works¶
- Detect chessboard corners in the images using
cv2.findChessboardCorners()
. - Refine corner detection for accuracy using
cv2.cornerSubPix()
. - Compute camera calibration using
cv2.calibrateCamera()
. - Save calibration parameters to a file using
np.savez()
.
Task¶
Write a script that:
- Loads all the captured chessboard images.
- Detects chessboard corners and displays them for human inspection.
- Computes the camera matrix and distortion coefficients.
- Saves the results to
calibration.npz
.
Hints¶
- Chessboard pattern size:
6x9
(rows x columns). - Use
np.mgrid
to generate a 3D representation of chessboard points. Note that you can measure the exact corner positions in metric values or simply use the size of one chessboard field as 1. -
Use
cv2.drawChessboardCorners()
to visualize the corners. Human inspection means simply that you check if all corners have been detected properly. -
Challenge: Compute and display the re-projection error after calibration. What does the error mean? Compare the values other students get or how it changes using less or more images or even bad images with blurred corners.
Step 3: Undistorting the Webcam Feed¶
Now that we have calibration data, we can undistort the live webcam feed.
How It Works¶
- Load the calibration parameters (
calibration.npz
). - Capture a frame from the webcam.
- Use
cv2.undistort()
to remove distortion. - Display both the original and undistorted images.
Task¶
Write a script that:
- Loads the saved calibration data.
- Opens the webcam and captures frames.
- Applies
cv2.undistort()
to remove distortion. - Displays both the original and undistorted frames side by side.
Hints¶
- Use
np.load()
to load saved parameters. -
Use
cv2.imshow()
to display multiple frames at once. -
Challenge: Display a difference image that highlights distortion effects before and after correction.
Step 4: Rendering a 3D Coordinate System into the Image¶
With the camera calibrated, we can render a 3D coordinate system into the image by detecting the chessboard and overlaying 3D axes.
How It Works¶
- Load the calibration parameters (
calibration.npz
). - Detect chessboard corners in the live feed.
- Compute the camera's position using
cv2.solvePnP()
. - Project 3D coordinate axes onto the image using
cv2.projectPoints()
. - Draw the 3D axes onto the image.
Task¶
Write a script that:
- Loads the calibration data.
- Detects a chessboard in the webcam feed.
- Computes the camera pose using
cv2.solvePnP()
. - Projects and draws a 3D coordinate system onto the image.
Hints¶
- The axes should be of size
3x3
units in world coordinates. - Use
cv2.line()
to draw the X, Y, and Z axes in red, green, and blue. -
This task is based on the next OpenCV tutorial: Pose Estimation.
-
Challenge: Modify the script to overlay a virtual 3D object (e.g., a cube) on top of the chessboard.
Final Thoughts¶
By completing this workshop, you have:
- Captured images for calibration.
- Computed and stored camera calibration parameters.
- Used those parameters to correct distortion in real time.
- Rendered a 3D coordinate system into the image.
Extra Challenge¶
- Try calibrating with a different calibration pattern (e.g., circles) and observe how it affects the results.
Grading¶
For this workshop nothing has to be handed in. Active participation is enough.