Camera#
Basic Camera use#
The Camera class acts as a simple video reader. Give it a path to a video file and it will read it.
import sportslabkit as slk
# Get a video
dataset_path = slk.datasets.get_path("wide_view")
path_to_mp4 = sorted(dataset_path.glob("videos/*.mp4"))[0]
cam = slk.Camera(path_to_mp4)
frame = cam[0] # Get the first frame
print(frame.shape)
(1000, 6500, 3)
Warning: The functions below are still a work in progress and are subject to API changes.
Advanced Camera setup#
SportsLabKit is designed to use either a single camera or multiple cameras. In this example we will use a two camera setup.
For each camera the following information is required in the yaml file:
label- a unique label for the camera. EitherLeftorRightis used in this example.video_path- The path to the video file.keypoint_xml- The path to the xml file containing the keypoints.calibration_video_path- The path to the video file used for calibration.x_range- The x range of the camera.y_range- The y range of the camera.camera_matrix- The camera matrix of the camera.camera_matrix_path- The path to the camera matrix file.distortion_coefficients- The distortion coefficients of the camera.distortion_coefficients_path- The path to the distortion coefficients file.
Note that usually a multicamera setup can be used to drastically improve the performance of the tracking by methods such as triangulation. However, this is not implemented yet.
Defining the camera ranges#
First, the range that each camera is resposible for handling detections for is defined. This is done by defining the x and y ranges in the yaml file.

In the example above, the Blue Cam is responsible for the x range from 0~52.5 and the Red Cam is responsible for the x range from 52.5~105. The y range is defined as the same, 0~68, for both cameras.
In the yaml file this will be defined as:
- label: Blue Cam
x_range:
- 0
- 52.5
y_range:
- 0
- 68
- label: Red Cam
x_range:
- 52.5
- 105
y_range:
- 0
- 68
Although not at all perfect, this setup allows the number of cameras to be increased to multiple cameras or decresed to one wide angle camera.
import sportslabkit as slk
cfg = slk.utils.load_config('./assets/config.yml')
slk.logger.inspect(cfg)
inspect:0137 💬| Inspecting: ({'cameras': [{'label': 'left', 'video_path': '../../data/raw/left_camera.mp4', 'keypoint_xml': '../../data/raw/left_keypoints.xml', 'calibration_video_path': '../../data/raw/left_checkerboard_images/', 'x_range': [0, 52.5], 'y_range': [0, 68], 'camera_matrix': None, 'camera_matrix_path': None, 'distortion_coefficients': None, 'distortion_coefficients_path': None}, {'label': 'right', 'video_path': '../../data/raw/right_camera.mp4', 'keypoint_xml': '../../data/raw/right_keypoints.xml', 'calibration_video_path': '../../data/raw/right_checkerboard_images/', 'x_range': [52.5, 105], 'y_range': [0, 68], 'camera_matrix': None, 'camera_matrix_path': None, 'distortion_coefficients': None, 'distortion_coefficients_path': None}], 'detection': {'model_name': 'yolov5x', 'size': 3000, 'batch_size': 1, 'filter_range': True}, 'outdir': '../../data/processed/'},)
â•─────────────────────────────────── <class 'omegaconf.dictconfig.DictConfig'> ───────────────────────────────────╮ │ â•─────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ │ │ {'cameras': [{'label': 'left', 'video_path': '../../data/raw/left_camera.mp4', 'keypoint_xml': │ │ │ │ '../../data/raw/left_keypoints.xml', 'calibration_video_path': '../../data/raw/left_checkerboard_images/', │ │ │ │ 'x_range': [0, 52.5], 'y_range': [0, 68], 'camera_matrix': None, 'camera_matrix_path': None, │ │ │ │ 'distortion_coefficients': None, 'distortion_coefficients_path': None}, {'label': 'right', 'video_path': │ │ │ │ '../../data/raw/right_camera.mp4', 'keypoint_xml': '../../data/raw/right_keypoints.xml', │ │ │ │ 'calibration_video_path': '../../data/raw/right_checkerboard_images/', 'x_range': [52.5, 105], 'y_range': │ │ │ │ [0, 68], 'camera_matrix': None, 'camera_matrix_path': None, 'distortion_coefficients': None, │ │ │ │ 'distortion_coefficients_path': None}], 'detection': {'model_name': 'yolov5x', 'size': 3000, 'batch_size': │ │ │ │ 1, 'filter_range': True}, 'outdir': '../../data/processed/'} │ │ │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ cameras = [{'label': 'left', 'video_path': '../../data/raw/left_camera.mp4', 'keypoint_xml': │ │ '../../data/raw/left_keypoints.xml', 'calibration_video_path': │ │ '../../data/raw/left_checkerboard_images/', 'x_range': [0, 52.5], 'y_range': [0, 68], │ │ 'camera_matrix': None, 'camera_matrix_path': None, 'distortion_coefficients': None, │ │ 'distortion_coefficients_path': None}, {'label': 'right', 'video_path': │ │ '../../data/raw/right_camera.mp4', 'keypoint_xml': '../../data/raw/right_keypoints.xml', │ │ 'calibration_video_path': '../../data/raw/right_checkerboard_images/', 'x_range': [52.5, 105], │ │ 'y_range': [0, 68], 'camera_matrix': None, 'camera_matrix_path': None, 'distortion_coefficients': │ │ None, 'distortion_coefficients_path': None}] │ │ detection = {'model_name': 'yolov5x', 'size': 3000, 'batch_size': 1, 'filter_range': True} │ │ outdir = '../../data/processed/' │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
Camera calibration#
In order to reduce the distortion of the camera lense and straighten the lines of pitch, the camera is calibrated. This is done by using a video or a set of images containing a checkboard pattern from multiple angles.

Record a short video of the checkboard pattern and add the path to the yaml file.
Homography Transformation#
TODO: This section needs its own notebook.

Load the camera objects#
Most of the information above (camera ranges, calibration, homography matrix etc.) is specific to the camera. Therefore it makes sense to create a Camera object to store this information. Below is an example of how to create a Camera object.
For more detail on what the Camera object does, read the documentation of the Camera class.
# from sportslabkit.camera import load_cameras
# cameras = load_cameras(cfg['cameras'])
# print(f"Loaded {len(cameras)} cameras")
# WIP