The Silent Invigilator: Multi-Modal Real-Time Exam Surveillance using Deep Learning and Spatial-Temporal Anomaly Scoring
Surveillance of academic assessments is critical for maintaining academic integrity. However, manual invigilation is subject to human fatigue, cognitive overload, and subconscious bias. This repository presents The Silent Invigilator, an autonomous, non-intrusive exam invigilation system that integrates real-time computer vision, deep learning inference, and spatial-temporal anomaly scoring to monitor and flag suspicious candidate behavior.
By fusing keypoint-based geometric tracking (gaze, head orientation, and facial structures) with object detection (YOLOv8) and student tracking (ByteTrack), the system constructs a multi-modal behavioral vector for each student. A temporal sliding-window risk accumulator filters transient physiological movements (such as blinking or natural adjustments) while registering persistent, high-confidence malpractice patterns. The system includes a dual deployment topology: a standalone, localized desktop runtime and a full-stack Flask-based dashboard for remote administration.
The Silent Invigilator is designed around a decoupled, multi-client ecosystem consisting of a high-concurrency Flask backend server, a localized standalone desktop client, an administrative web console, and a cross-platform mobile invigilation application.
graph LR
subgraph Capture Hardware
Webcam[USB Webcam / Camera Source]
end
subgraph Desktop Client [Localized Client]
SI[silent_invigilator.py <br>Standalone GUI]
end
subgraph Central Server [Flask Backend & DB]
App[app.py <br>REST & WebSocket API]
DB[(SQLite DB <br>invigilator.db)]
Logger[Background Logger Thread]
App <--> Logger
Logger <--> DB
end
subgraph Client Applications [Invigilator Interfaces]
Web[Web-Based console <br>Socket.IO Telemetry]
Mobile[Flutter Mobile App <br>JWT Auth & Alerts]
end
Webcam --> SI
Webcam --> App
SI -- Local DB Logs --> DB
App <--> Web
App <--> Mobile
The system processes input video streams through a modular, multi-layered sequential pipeline:
- Feature Extraction Layer:
- MediaPipe Face Mesh: Extracts dense 3D facial geometry (468 landmarks) and iris structures in both the desktop client and web server.
- MediaPipe Hands: Utilized in the localized desktop client to extract bilateral hand skeletons (21 landmarks per hand) for proximity tracking.
- MediaPipe Pose: Pre-initialized in the desktop client to support future structural joint alignment hooks (currently bypassed in active scoring).
- Deep Learning Inference Layer: Runs a lightweight YOLOv8 model (
yolov8n.pt/yolov8s.pt) for prohibited object detection (mobile phones and books/papers) in parallel with an IoU-based tracking filter (ByteTrack) to identify and track multiple candidates. - Heuristic and Scoring Layer: Evaluates extracted geometric parameters, updates a sliding-window temporal queue, computes a composite anomaly score, and writes incidents asynchronously to an SQLite database.
graph TD
A[Video Capture Thread] --> B[Frame Processing Dispatcher]
B --> C[Geometric Feature Extraction]
B --> D[Deep Learning Inference]
C --> C1[MediaPipe Face Mesh <br>468 Landmarks & Irises]
C -- "Pre-initialized (Future Hook)" --> C2[MediaPipe Pose <br>Body Joint Landmarks]
C --> C3[MediaPipe Hands <br>Bilateral Hand Landmarks - Desktop Only]
D --> D1[YOLOv8 Object Detection <br>Cell Phone & Book Classes]
D --> D2[ByteTrack Multi-Person Tracker <br>Persistent Student Tracking]
C1 --> E1[3D Head Pose solverPnP <br>Pitch, Yaw]
C1 --> E2[Eye Gaze Ratio Analysis <br>Iris Deviation Vectors]
C1 --> E3[Mouth Aspect Ratio <br>Oral Activity Detection]
C3 --> E4[Hand-to-Face Proximity - Desktop Only]
D1 --> F1[Bounding Box Intersections <br>IoU Merging]
D2 --> F2[Track ID Mapping]
E1 & E2 & E3 & E4 & F1 & F2 --> G[Track-Level Scoring Engine]
G --> H[Temporal Risk Accumulator <br>EMA + Sliding Window]
H --> I[Malpractice Alert Dispatcher]
I --> J[Background DB Logger <br>SQLite logs & alerts]
I --> K[Websocket Real-Time Event Emitters]
To estimate head orientation in three-dimensional space without requiring dedicated depth sensors, the system solves the Perspective-n-Point (PnP) problem. Given a set of
Let
Where:
-
$s$ is an arbitrary scale factor. -
$K$ is the camera intrinsic matrix, initialized using the frame resolution boundaries and focal length approximation:
-
$R \in SO(3)$ is the rotation matrix, and$T \in \mathbb{R}^3$ is the translation vector.
We compute
The rotation matrix
A violation is flagged if
Gaze tracking calculates the ratio of the iris center position relative to the horizontal boundaries of the eye. This index is robust against individual variations in eye shapes.
Let
Where
The horizontal gaze direction is classified based on the average ratio
-
Right:
$\gamma_{\text{avg}} < 0.40$ -
Left:
$\gamma_{\text{avg}} > 0.60$ -
Center:
$0.40 \le \gamma_{\text{avg}} \le 0.60$
To detect oral communication (talking or reading aloud), the system measures the Mouth Aspect Ratio (MAR) over a sliding temporal window.
Using the mouth coordinates, let
The raw MAR values are smoothed using an exponential moving average (EMA) with a smoothing factor
A talking event is triggered if
For detecting unauthorized physical items (such as mobile phones and paper/books), the system runs YOLOv8 inference. The network outputs bounding boxes represented as 67 for cell phone, 73 for book) and
To enhance small-object detection, the system integrates Slicing Aided Hyper Inference (SAHI). The frame is partitioned into overlapping slices of size
Aggregated predictions are resolved using Non-Maximum Suppression (NMS) with an Intersection-over-Union (IoU) threshold of
For each tracked student, a risk score
where
Where:
-
$O_{\tau} \in \{0, 0.45, 1.0\}$ indicates object detection status ($1.0$ if a phone is detected,$0.45$ if a book/paper is detected, and$0.0$ otherwise). If a phone is present,$R_{\tau}$ is set to$\max(R_{\tau}, 85)$ . -
$E_{\tau}$ is the rolling gaze deviation (percentage of the last 90 frames where gaze was not Center). -
$H_{\tau}$ is the rolling head pose deviation (percentage of the last 90 frames where head pose was not Center). -
$D_{\tau}$ is the rolling head down-tilt deviation (percentage of the last 90 frames where head pose was Down). -
$C_{\tau}$ is the short-term temporal alignment factor (percentage of the last 20 frames where gaze or head pose deviated from center).
When the overall score exceeds
To evaluate the feasibility of real-time deployment across various client configurations, a profiling run was conducted measuring frame processing delays (in milliseconds) and throughput (FPS) across five pipeline configurations on both CPU and GPU hardwares.
- Baseline Overhead: Camera frame ingestion and buffer updating consume minimal overhead (~1.8 ms to 2.1 ms), allowing high-frequency grabbing.
- Feature Extraction Core: FaceMesh evaluation is highly optimized, executing at ~8.2 ms on GPU (~122 FPS) and ~24.5 ms on CPU (~41 FPS), proving its capability as a primary heuristic checker.
- Deep Learning Bottleneck: The addition of YOLOv8n object detection increases latency to ~21 ms on GPU and ~82.4 ms on CPU. When SAHI slicing hyper-inference is activated for detecting distant small objects, latency escalates to ~58.6 ms on GPU (~17 FPS) and ~315 ms on CPU (~3.2 FPS).
-
Mitigation Recommendation: In CPU-bound standalone environments, SAHI slicing should be disabled, and YOLOv8 inference cadence should be set to execute every
$N=15$ frames to maintain real-time throughput.
The codebase is structured into four primary sub-systems:
├── backend/
│ ├── app.py # Flask Web API, websocket server, & dashboard router
│ ├── camera.py # Multi-threaded frame grabber, MediaPipe wrappers, and YOLOv8 pipeline
│ ├── silent_invigilator.py # Standalone OpenCV GUI executable with logging utilities
│ ├── requirements.txt # Core Python dependencies
│ ├── static/ # CSS styling sheets and JavaScript dashboard charts
│ └── templates/ # HTML structural layouts for the monitoring dashboard
├── mobile_app/
│ ├── lib/ # Dart application source code (Flutter)
│ │ ├── main.dart # Mobile application entrypoint
│ │ ├── screens/ # Login, Admin, Teacher dashboard views
│ │ └── services/ # REST API clients (JWT auth, telemetry logs)
│ └── pubspec.yaml # Flutter package configuration and assets
To prevent network request latency from dropping the frame rate of the ML pipeline, the camera interface runs on a separate thread. This thread continuously grabs frames from the hardware camera buffer and updates a shared memory location, allowing the main processor thread to query the latest frame asynchronously.
A self-contained Python application that opens an OpenCV window showing the camera stream with HUD overlays. It records the session, computes risk thresholds, and writes a structural JSON report on exit.
A Flask web server that handles real-time MJPEG video streaming. It exposes JSON endpoints for real-time telemetry (anomaly graphs, active violations, and total counts) and displays a Brutalist-style dashboard for invigilators.
- Python 3.10 or higher
- Pip (Python Package Installer)
- C++ Build Tools (required for specific dependency compilations under Windows)
- Webcam or network-attached IP camera
-
Clone the Repository and navigate to the project directory:
cd silent-invigilator -
Initialize a Virtual Environment:
python -m venv .venv
-
Activate the Environment:
- Windows (PowerShell):
.venv\Scripts\Activate.ps1
- Linux / macOS:
source .venv/bin/activate
- Windows (PowerShell):
-
Install Dependencies:
cd backend pip install -r requirements.txt
To launch the OpenCV-based desktop window, run the following:
cd backend
python silent_invigilator.py- Press Q to exit and write the database/JSON logs.
- Press R to reset active scores.
- Press S to save an intermediate snapshot.
To start the web server and view the dashboard in a web browser:
cd backend
python app.pyOpen a web browser and navigate to http://127.0.0.1:5000. The interface will display a real-time graph of the candidate's anomaly score, active alerts, and an annotated video feed.
All system thresholds can be customized in the configuration dictionary within the SilentInvigilator class (silent_invigilator.py):
self.thresholds = {
'head_yaw_limit': 25, # Maximum allowable head yaw rotation (degrees)
'head_pitch_limit': 20, # Maximum allowable head pitch rotation (degrees)
'gaze_center_min': 0.35, # Relative iris position lower bound (0-1)
'gaze_center_max': 0.65, # Relative iris position upper bound (0-1)
'mouth_open_ratio': 0.5, # Mouth Aspect Ratio threshold for talking detection
'phone_confidence': 0.45, # Minimum confidence score for YOLO phone detection
'sustained_frames': 45, # Frame threshold for sustained anomalies (~1.5s)
}Calculated dynamically per frame based on active violations:
- Prohibited Object (Phone): +50 points
- Multiple Face Detection: +40 points
- Absent / No Face Detected: +30 points
- Mouth Open / Talking (MAR): +25 points
- Out-of-bounds Head Yaw Rotation: +20 points
- Out-of-bounds Head Pitch Rotation: +20 points
- Eye Gaze Aversion: +15 points
- Hand Near Face Proximity: +10 points
- Sustained Head Turn / Talking streak: +20 points
Computes a rolling temporal cheating score (
- Prohibited Object (Phone/Book): Weight 0.40 (Enforces immediate minimum score of 85 if phone is present)
- Eye Gaze Aversion (
$E_{\tau}$ ): Weight 0.22 - Head Pose Out-of-bounds (
$H_{\tau}$ ): Weight 0.16 - Head Down-tilt Pose (
$D_{\tau}$ ): Weight 0.14 - Short-term Temporal Anomaly Correlation (
$C_{\tau}$ ): Weight 0.08
To achieve real-time performance on lower-tier hardware (e.g., integrated GPUs or older CPUs):
-
Limit Resolution: Initialize the video capture stream at
$640 \times 480$ rather than$1280 \times 720$ . -
Frame Skipping: Modify the main loops to perform YOLOv8 inferences only once every
$N$ frames (e.g.,$N=15$ ), while using MediaPipe landmark interpolation for the intermediate frames. -
Hardware Acceleration: If an NVIDIA GPU is available, install CUDA-supported PyTorch to accelerate YOLOv8 model evaluations:
pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118
- Google MediaPipe: Keypoint tracking and landmark geometries.
- Ultralytics YOLOv8: Object detection framework.
- OpenCV: Open-source Computer Vision library.
- solvePnP: Perspective-n-Point pose calculation method.


