How to Add New Known Faces to the Database Dynamically in Multi-Cam Face Tracker

You can dynamically add new known faces using the built-in Face Manager UI or programmatically via FaceDetector.add_known_face(), which extracts embeddings, saves images to disk, and updates the in-memory registry while optionally persisting to SQLite.

The multi-cam-face-tracker repository implements a flexible dual-layer architecture for face enrollment that supports real-time updates without application restarts. Whether you need to register new identities through the Qt-based graphical interface or automate enrollment via Python scripts, the system provides distinct pathways for both in-memory recognition and persistent database storage.

Understanding the Dual-Layer Storage Architecture

The system maintains known faces in two complementary layers to balance real-time performance with data persistence.

In-Memory Registry for Real-Time Recognition

The FaceDetector class maintains an in-memory list called known_faces containing KnownFace objects. Each object stores the person's name, facial embedding vector, and image path. This registry lives in core/face_detection.py and provides the sub-millisecond lookup times required for real-time video processing.

Persistent SQLite Database

For long-term storage across application restarts, the system optionally uses a SQLite database managed by the FaceDatabase class in core/database.py. This stores the same fields plus timestamps, enabling external scripts to enroll faces without launching the full application UI.

Adding Faces via the Face Manager UI

The primary method for enrolling new faces uses the FaceManagerDialog class in ui/face_manager.py, which provides a guided workflow for importing and validating face images.

Importing and Previewing Images

The enrollment process begins with FaceManagerDialog.import_image(), which opens a file chooser dialog and loads the selected image using OpenCV. The method displays a preview within the dialog and pre-fills the name field using the file stem for convenience.

Validating and Storing the Face

When the user clicks "Add Face", the dialog invokes FaceManagerDialog.add_face(), which validates the input and delegates to the detector:


# ui/face_manager.py – add_face()

success = self.face_detector.add_known_face(
    self.current_image, name, self.known_faces_dir)

Behind the scenes, FaceDetector.add_known_face() in core/face_detection.py performs three critical operations:

  1. Extracts the facial embedding using the InsightFace model
  2. Saves the image to disk with a timestamped filename
  3. Appends a new KnownFace object to the in-memory registry

# core/face_detection.py – add_known_face()

faces = self.detect_faces(image)                     # get embedding

face_path = save_dir / f"{name}_{timestamp}.jpg"    # store image

cv2.imwrite(str(face_path), image)
self.known_faces.append(KnownFace(name, face.embedding, str(face_path)))

The UI immediately refreshes the face list, and the system can recognize the newly enrolled identity without requiring a restart.

Programmatically Adding Known Faces

For automation scenarios such as batch enrollment or API endpoints, you can bypass the UI and interact directly with the detection and database layers.

Using FaceDetector for In-Memory Updates

To add a face programmatically without database persistence:

import cv2
from core.face_detection import FaceDetector
from pathlib import Path

# Initialize with the same configuration used by the application

detector = FaceDetector(config)

# Load existing faces to maintain current registry

detector.load_known_faces(Path("known_faces"))

# Read new image as NumPy array

img = cv2.imread("new_person.jpg")

# Add to in-memory registry and save image to disk

detector.add_known_face(img, "Alice", "known_faces")

Persisting to SQLite with FaceDatabase

To ensure the face survives application restarts without re-scanning the image directory, persist the embedding to the SQLite database:

from core.database import FaceDatabase

# Initialize database connection

db = FaceDatabase("data/faces.db")

# Retrieve embedding from the newly added face (last entry in registry)

embedding = detector.known_faces[-1].embedding.tobytes()

# Insert into persistent storage

db.add_known_face(
    name="Alice",
    embedding=embedding,
    image_path="known_faces/Alice_1700001234.jpg"
)

Loading Known Faces on Application Startup

When the application initializes, FaceDetector.load_known_faces() in core/face_detection.py scans the known_faces_dir, recomputes embeddings for each image using the InsightFace model, and repopulates the in-memory registry. This ensures that faces added via either the UI or direct file system manipulation are available for recognition.


# core/face_detection.py – load_known_faces()

for face_file in known_faces_dir.glob('*.*'):
    img = cv2.imread(str(face_file))
    faces = self.model.get(img)
    self.known_faces.append(KnownFace(face_file.stem, faces[0].embedding, str(face_file)))

Summary

  • The multi-cam-face-tracker uses a dual-layer architecture: an in-memory registry for real-time recognition and an optional SQLite database for persistence.
  • UI-driven enrollment uses FaceManagerDialog in ui/face_manager.py to import images, validate inputs, and call FaceDetector.add_known_face().
  • Programmatic enrollment allows direct calls to FaceDetector.add_known_face() for immediate in-memory updates, with optional FaceDatabase.add_known_face() for SQLite persistence.
  • Faces are stored as timestamped images in the known_faces_dir and reloaded automatically on startup via FaceDetector.load_known_faces().

Frequently Asked Questions

Can I add faces without using the GUI?

Yes. You can programmatically add faces by importing FaceDetector from core/face_detection.py, initializing it with your configuration, and calling add_known_face(image, name, save_dir) with a NumPy array image. This bypasses the Qt interface entirely and works for batch processing or API integrations.

Where are the face images physically stored?

Face images are saved to the directory specified as known_faces_dir (typically known_faces/ in the project root) with timestamped filenames in the format {name}_{timestamp}.jpg. The FaceDetector.add_known_face() method in core/face_detection.py handles the file I/O using OpenCV's imwrite function.

Do I need to restart the application after adding a new face?

No. The system supports dynamic updates without restarts. When you add a face via the UI or programmatically, FaceDetector.add_known_face() immediately appends the new KnownFace object to the in-memory registry. The recognition pipeline uses this live registry for matching, making the new identity available for detection in subsequent video frames instantly.

How does the system handle duplicate names?

The current implementation in core/face_detection.py does not enforce unique name constraints in the add_known_face method. If you add multiple faces with the same name, each creates a separate KnownFace entry with a unique timestamped filename. During recognition, the system matches based on embedding similarity rather than name uniqueness, so duplicates will exist as separate entries in the registry. To prevent duplicates, implement a check against self.known_faces names before calling add_known_face.

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 →