Real-time RTSP Video Streams

Monitor raw OpenCV and GStreamer RTSP streams in real-time. VigilCV operates fast enough to validate 60 FPS 4K streams on a single CPU core.

import cv2
from vigilcv import VisionSentinel

sentinel = VisionSentinel()
cap = cv2.VideoCapture("rtsp://camera_ip:554/stream")

while True:
    ret, frame = cap.read()
    if not ret:
        break
        
    metrics = sentinel.audit(frame)
    if metrics.is_degraded:
        # Trigger alarm or skip frame
        cv2.putText(frame, "CORRUPTED", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
        
    cv2.imshow("Stream", frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

API Reference

VisionSentinel

The primary entry point for single-image and stream-based quality auditing.

Constructor

VisionSentinel(
    blur_threshold: float = 100.0,
    min_entropy: float = 3.0,
    max_underexposure_ratio: float = 0.20,
    max_overexposure_ratio: float = 0.20,
    raise_on_fail: bool = True,
)
ParameterTypeDefaultDescription
blur_thresholdfloat100.0Minimum acceptable Laplacian variance
min_entropyfloat3.0Minimum Shannon entropy in bits
max_underexposure_ratiofloat0.20Max fraction of dark-clipped pixels (< 10)
max_overexposure_ratiofloat0.20Max fraction of saturated pixels (> 245)
raise_on_failboolTrueRaise QualityThresholdExceeded on failure, or return metrics

Methods

guard(source) → QualityMetrics

Run all quality gates on a single image. Raises CorruptImageError for unreadable files.

metrics = sentinel.guard("path/to/image.jpg")
metrics = sentinel.guard(Path("image.png"))
metrics = sentinel.guard(io.BytesIO(image_bytes))  # FastAPI UploadFile

audit_stream(cap, sample_every=1) → Iterator[tuple[np.ndarray, QualityMetrics | None]]

Wrap an OpenCV VideoCapture with quality telemetry.

for frame, metrics in sentinel.audit_stream(cap):
    if metrics and metrics.passed:
        process(frame)

BatchAuditor

Multi-threaded batch processor for auditing directories.

Constructor

BatchAuditor(
    directory: str | Path,
    workers: int = 4,
    sentinel: VisionSentinel | None = None,
    glob_pattern: str = "**/*.{jpg,jpeg,png,webp}",
)

Methods

run() → AuditSummary

Execute the full audit. Returns an AuditSummary dataclass.

auditor = BatchAuditor("dataset/train/", workers=8)
summary = auditor.run()

QualityMetrics

Immutable dataclass returned by VisionSentinel.guard().

@dataclass(frozen=True)
class QualityMetrics:
    path: Path | None           # Source file path (None for BytesIO)
    blur_score: float           # Laplacian variance
    shannon_entropy: float      # Shannon entropy (bits)
    underexposure_ratio: float  # Fraction of dark-clipped pixels
    overexposure_ratio: float   # Fraction of saturated pixels
    width: int                  # Image width in pixels
    height: int                 # Image height in pixels
    passed: bool                # True if all gates passed
    warnings: list[str]         # Human-readable failure reasons
    latency_ms: float           # Wall-clock audit time in milliseconds

AuditSummary

Returned by BatchAuditor.run().

@dataclass(frozen=True)
class AuditSummary:
    total_images: int
    valid_images: int
    corrupted_count: int
    blurred_count: int
    underexposed_count: int
    overexposed_count: int
    throughput_fps: float
    total_duration_s: float
    drift_report: DriftReport | None  # Only if baseline provided
    per_image_metrics: list[QualityMetrics]

DriftReport

Returned by DriftEngine.detect().

@dataclass(frozen=True)
class DriftReport:
    is_drifted: bool
    wasserstein_distance: float
    mmd_score: float
    top_drift_features: list[str]
    reference_n: int
    query_n: int
    threshold: float

Exceptions

from vigilcv.exceptions import (
    VigilCVError,              # Base exception
    CorruptImageError,         # Unreadable / truncated file
    QualityThresholdExceeded,  # Quality gate failure
    DriftDetectedError,        # Distribution drift exceeds threshold
)

All exceptions carry the offending QualityMetrics as .metrics attribute for inspection:

try:
    sentinel.guard("image.jpg")
except QualityThresholdExceeded as e:
    print(e.metrics.blur_score)  # Access the actual scores
    print(e.metrics.warnings)

VisionSentinel Interface

The primary class for executing heuristic validations. It encapsulates SIMD-accelerated C-bindings and provides a zero-overhead Python interface.

Parameters

ParameterTypeDefaultDescription
blur_thresholdfloat110.0Laplacian variance threshold for blur detection.
entropy_minfloat3.85Minimum Shannon entropy required to pass validation.
specular_clip_limitfloat0.35Maximum allowed ratio of clipped pixels.
enable_fast_spectralboolTrueAccelerate FFT via CPU vectorization.

Methods

  • audit_stream(buffer: np.ndarray) -> SentinelMetrics
  • audit(image: Image.Image | np.ndarray) -> SentinelMetrics

Batch Auditor

Assess massive datasets on disk with parallelized DriftEngine operations.

from vigilcv.core.drift import DriftEngine

engine = DriftEngine()
engine.fit(reference_directory="dataset/train/")
engine.save("baseline.pkl")

report = engine.detect(query_directory="dataset/new_batch/")

if report.is_drifted:
    print(f"DRIFT DETECTED: {report.wasserstein_distance:.4f} W1")

CLI Reference

VigilCV exposes a fully-featured POSIX CLI for bash scripting and CI/CD pipelines.

# Inspect a single image
vigilcv inspect photo.jpg --blur-threshold 150

# Audit a massive directory in parallel
vigilcv audit dataset/train/ --workers 16 --report quality_report.html

# Detect distribution drift against baseline
vigilcv drift dataset/new/ --baseline baselines/prod_v1.pkl --threshold 0.20