Skip to content

Pipeline lifecycle

The Pipeline class manages the lifecycle of hardware video capture, worker thread pools, neural inference, and temporal event generation.

Lifecycle overview

Video sources

pipe.start(source_spec) accepts three types of input:

  1. Webcam capture:
    python
    pipe.start("camera:0")  # Default camera
    pipe.start("camera:1")  # Secondary webcam
  2. Video file playback:
    python
    pipe.start("file:tests/fixtures/sample_exam.mp4")
  3. Image sequence directory:
    python
    pipe.start("dir:frames_dump/")

Polling vs events

The pipeline provides two distinct query mechanisms:

1. Instantaneous signals (snapshot())

pipe.snapshot() returns a Signals object containing the raw, unfiltered detections from the most recent frame:

  • Detected faces with bounding boxes and 5 facial keypoints.
  • Head pose Euler angles (yaw, pitch, roll).
  • Gaze direction vectors (yaw, pitch).
  • Detected prohibited objects (phones, laptops, books).

snapshot() is level-triggered and non-blocking. It returns None if no frame has been processed yet.

2. Discrete violation events (events())

pipe.events() drains all new temporal events evaluated by the FusionEngine since the last call:

  • ViolationStarted: A condition (e.g. head_turned_away) has persisted past its configured onset hold timer.
  • ViolationEnded: The condition has ceased and cleared its release hold timer.
  • CalibrationProgress / CalibrationComplete: Head and gaze calibration progress.
  • Degraded / Recovered: Performance drops or recovery alerts.

Context manager pattern

Using Python's with statement ensures threads and camera resources are released cleanly even if an unhandled exception occurs:

python
import vigilo_stream

with vigilo_stream.Pipeline(models_dir="models") as pipe:
    pipe.start("camera:0")

    while pipe.is_running():
        frame = pipe.poll_frame()
        # Processing loop...
# Hardware capture and background threads are stopped automatically on exit

Face identity enrollment

To verify that the candidate sitting for the exam is the same person throughout the session, call pipe.enrol():

python
# Request enrollment on the next clear face detection
pipe.enrol()

# Check enrollment status
if pipe.is_enrolled():
    print("Candidate face enrolled successfully.")

Once enrolled, the ArcFace identity worker compares subsequent frames against the enrolled feature embedding and produces identity_match similarity scores.

Hot-reloading configuration

You can update detection thresholds, hysteresis limits, and hold timers at runtime without restarting capture:

python
new_config_toml = """
[models.face]
score_threshold = 0.85

[fusion.head_pose]
yaw_threshold_deg = 25.0
onset_hold_ms = 800
"""

pipe.update_config(new_config_toml)

Released under the AGPL-3.0 License.