Computer Vision — 2025

FaceAppFace Recognition with Liveness & Geofencing

University attendance is trivially cheatable — a friend signs you in, a photo fools the camera, a VPN fakes your location. FaceApp is a defence-in-depth answer built entirely on commodity hardware: eight independent verification layers, no infrared, no depth sensor, no GPU.

Role
Sole author — research, architecture, build, evaluation
Client
MSc Dissertation · Distinction 92
Year
2025
Discipline
Computer Vision

The problem

Roll-call, paper sheets, smart cards and QR codes all share one flaw: they verify a token, not a person. Adding face recognition alone just moves the attack — a printed photo, a phone screen, or an OBS virtual camera defeats naive verification. And even a perfect face check says nothing about whether the student is actually in the room.

The approach

I built a three-tier polyglot system: Rails 8.1 owns authentication and persistence, a Flask 3.0 service hosts the verifier and the ONNX Runtime inference path, and a single shared secret binds the trust boundary. Identity comes from 512-dimensional InsightFace buffalo_l ArcFace embeddings at a calibrated 0.45 cosine threshold. Liveness fuses an active randomised head-pose challenge with passive MediaPipe landmarks, a MiniFASNet anti-spoof CNN, FFT screen-artefact analysis, depth-motion and camera-authenticity heuristics — plus a wrong-action fast-fail that rejects an attack inside a single frame. Location is bound cryptographically: an HMAC-SHA256 token fusing student ID, GPS, a nonce and an expiry, validated independently at both the Flask issuer and the Rails consumer, with a haversine geofence.

The outcome

1.8% equal-error rate over 300 verification trials. Across 350 presentation attacks in seven categories: printed photo 99.3% blocked, wrong-action 99.6%, tablet replay 97.1%, phone replay 96.7%, virtual camera 94.4%, paper mask 92.5% — roughly 96% aggregate. Per-frame liveness runs in 32.5ms on an Apple M2 with no GPU. All 1,000 tokens validated; tamper, replay and forged-GPS attempts were rejected 100% of the time. A 14-day pilot recorded zero successful proxy attempts. Graded 92 — Distinction.

Results

By the numbers.

Measured, not estimated
99.3%
Printed-photo attacks blocked
1.8%
Equal-error rate
32.5ms
Per-frame, CPU only
Stack

What it's built on.

10 components
Python Ruby on Rails 8.1 Flask 3.0 ONNX Runtime InsightFace ArcFace MediaPipe MiniFASNet OpenCV PostgreSQL HMAC-SHA256
Contact

Let's build
something honest.