Detect
OpenCV pulls and decodes the RTSP stream; YOLOv8n finds faces in each frame. ByteTrack assigns a persistent track ID so one person walking through is one subject, not forty.
A real-time face-recognition attendance system that runs entirely on the hardware already on site — a basic computer or a small edge device — with no cloud and no internet. Four neural networks in a Kafka-chained pipeline, a FAISS vector index, and an operator console whose whole job is to show you why the model kept or threw away every single face it saw.
4
Detection, face detection, head pose, recognition
512
Face embeddings, FAISS cosine index
51.7k
Lines — inference, tracking, clustering
79.5k
Lines across Python + NestJS + React

Cameras watch a workspace. An edge device — no internet required — detects every face, measures whether that face is good enough to trust, and only then matches it against an enrolled identity. The output is an attendance record nobody had to clock in for.
Face recognition demos are easy. Face recognition that runs 24/7 on modest on-site hardware, at night, on people walking past at an angle — that fails constantly. So the product is built around a confession:
Of 12,905 faces the camera found, only 3,632 were good enough to keep.
That 28% survival rate is not hidden; it is the main screen. Every rejected face shows the exact measurement that killed it and the exact limit it was measured against, and an operator who thinks the system is missing people can widen that limit and watch the numbers move. That feedback loop — model behaviour made legible and tunable by a non-engineer — is the actual engineering achievement.
Three OS processes, chained by Kafka topics, all writing to one Postgres. A face reaches an identity only by passing every gate, in order.
OpenCV pulls and decodes the RTSP stream; YOLOv8n finds faces in each frame. ByteTrack assigns a persistent track ID so one person walking through is one subject, not forty.
Landmark count, OpenCV Laplacian blur, face area, and head pose (yaw / pitch / roll via WHENet) each checked against a configured limit.
Most attrition happens here.Survivors are aligned, embedded to a 512-d face vector, and searched against a FAISS cosine index. Match or stranger.
Incrementally clusters ungrouped faces and suggests an enrolled identity for a human to confirm — incremental on purpose, because a full re-cluster would renumber every group and invalidate labels operators had already read.
A single grouping module (FAISS cosine + temporal tiebreaker + union-find) is the one definition of “are these the same person?”, called by both the review queue and the consolidator, so suggestions can never contradict the stored grouping.

This is what makes the explainability real rather than decorative. The console does not just report the model’s decisions — it is the control surface for them, and it speaks in consequences (“Increase: accepts faces that are more side-on; can reduce recognition accuracy”) rather than in hyperparameters.




x / 127.5 − 1.0 (scale-then-offset, not (x − 127.5) / 128) — so a threshold tuned on a laptop means the same thing on the deployed machine./media serves biometric crops openly, and that it is only acceptable on a trusted, firewalled network. Stating the limits is part of the work.