How to Add Multiple Cameras to the Multi-Cam Face Tracker: YAML Configuration Guide

To add multiple cameras to the Multi-Cam Face Tracker, create or edit the config/camera_config.yaml file to define each camera with a unique numeric ID, display name, and video source; the system automatically spawns capture threads and displays live feeds in the UI grid without requiring code modifications.

The aarambhdevhub/multi-cam-face-tracker repository provides a scalable architecture for facial recognition across several video sources simultaneously. By leveraging the CameraManager class and a declarative YAML configuration, you can integrate local webcams, IP cameras, and RTSP streams into a unified monitoring interface.

Configuring Multiple Cameras via YAML

The system discovers cameras exclusively through the config/camera_config.yaml file. When the application launches via main.py, the CameraManager instantiates and immediately calls load_config() to parse this file.

Create the file at config/camera_config.yaml with the following structure:

cameras:
  - id: 0
    name: "Front Door"
    source: 0
    enabled: true
    resolution:
      width: 1280
      height: 720
    fps: 30
    rotate: 0

  - id: 1
    name: "Backyard"
    source: "rtsp://192.168.1.45/stream1"
    enabled: true
    resolution:
      width: 640
      height: 480
    fps: 15
    rotate: 90

Each camera entry requires these parameters:

  • id – Unique integer identifier used internally by CameraManager to index self.frame_queues and track thread states.
  • name – Human-readable label displayed in the UI tabs and status messages.
  • source – Either a local device index (0, 1, etc.) or a network URL (rtsp://, http://).
  • enabled – Boolean flag; when true, CameraManager.start_all_cameras() automatically begins capture on startup.
  • resolution – Desired capture dimensions (width/height) requested from the driver.
  • fps – Target frames-per-second for the capture thread.
  • rotate – Rotation correction in degrees (0, 90, 180, 270) applied to each frame before processing.

How CameraManager Processes Multiple Streams

Located in core/camera_manager.py, the CameraManager class orchestrates parallel capture using dedicated threads. After parsing the YAML into CameraConfig dataclasses stored in self.cameras, the manager calls start_all_cameras() when the MainWindow initializes.

For every camera marked enabled: true, the manager:

  1. Creates a dedicated thread running _capture_frames(), which continuously reads from the video source.
  2. Stores the most recent frame in self.frame_queues[cam_id], a dictionary mapping camera IDs to thread-safe queues.
  3. Maintains running state flags to handle disconnections and reconnections gracefully.

The UI retrieves frames via get_all_frames(), which non-destructively peeks at each queue to display the latest image without blocking the capture threads.

Displaying and Controlling Cameras in the UI

The ui/main_window.py file implements the frontend logic. Upon initialization, setup_monitor_tab() automatically builds a video grid containing one panel per camera defined in the configuration file.

The interface provides two primary control mechanisms:

  • Automatic Grid Layout – The monitor tab displays all enabled cameras simultaneously, updating via a update_timer that polls CameraManager.get_all_frames() at regular intervals.
  • Manual Controls – The Controls tab contains a camera_combo dropdown listing all configured cameras. Users can click Start Camera or Stop Camera to manually manage individual streams, particularly useful for cameras set to enabled: false in the YAML or for restarting failed connections.

The status pane at the bottom of the Controls tab continuously reports each camera's operational state through update_status(), showing whether a thread is actively capturing or stopped.

Summary

  • Configuration-driven setup – Add multiple cameras by editing config/camera_config.yaml without touching Python source code.
  • Flexible source support – Mix local device indices (0, 1) with network RTSP/HTTP streams in the same configuration file.
  • Automatic thread management – CameraManager in core/camera_manager.py handles thread spawning, frame queuing, and resource cleanup internally.
  • Dynamic UI generation – ui/main_window.py renders video panels and controls automatically based on the YAML content.
  • Runtime control – Start and stop individual cameras manually through the Controls tab regardless of the initial enabled setting.

Frequently Asked Questions

What video sources can I use when adding multiple cameras?

You can specify local USB webcams using integer indices (0 for the first camera, 1 for the second) or network streams using standard URLs such as rtsp://192.168.1.100:554/stream or http://camera.local/video. The source field in camera_config.yaml accepts any string or integer that OpenCV's VideoCapture can parse.

How many cameras can I add to the system simultaneously?

The practical limit depends on your hardware's USB bandwidth, network capacity, and CPU cores. Each camera runs in a separate thread managed by CameraManager, so the system scales vertically until you exhaust I/O bandwidth or processing power for face detection. The configuration file structure supports unlimited entries, but you should test frame drop rates when exceeding 4-6 high-resolution streams.

Why does my camera appear offline despite correct YAML configuration?

Verify that the id values are unique integers and that no other application is locking the video device. For network cameras, ensure the RTSP URL is accessible from the host machine. Check the status pane in the Controls tab; if CameraManager fails to open a source in _capture_frames(), it will mark the camera as stopped, which you can retry using the Start Camera button.

Do I need to restart the application after editing camera_config.yaml?

Yes. The CameraManager loads and parses the YAML only once during MainWindow initialization in main.py. Changes to camera definitions, resolutions, or rotation settings require a full application restart to take effect. However, you can temporarily disable active cameras or start inactive ones through the Controls tab without restarting.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →