CCTV IQ - Face ID Attendance

At a glance

In shortA face-recognition attendance system on two office doorway cameras. It logs clock-in, clock-out and time inside, and answers questions about attendance in plain English.
ProblemTrack office attendance automatically, using the cameras already at the door.
What it doesRecognises enrolled people on two doorway cameras, records clock-in, clock-out and time inside with a face photo for each, and writes one Excel file per day.
How it worksFind faces, turn each into an embedding, match it against 182 people. Clock-in is the first sighting of the day on either camera; clock-out is the last.
Ask IrisType a question like "who was late this week?". Claude Haiku 4.5 on AWS Bedrock writes one SQL query, runs it, and answers from the rows.
Result0.31 s per frame (from 9.86 s) on an office PC. A score floor fitted to a hand-checked day removed every false name and lost no real person.
TechPython, InsightFace (SCRFD + antelopev2), OpenVINO on the Intel iGPU, FastAPI, SQLite, AWS Bedrock

Flow

  1. 2 doorway cameras
    RTSP, H.264
  2. Mask zones
    desks, clear glass
  3. Find + embed faces
    SCRFD + antelopev2 on iGPU
  4. Match
    182 people, floor 0.41
  5. Build the day
    first in, last out, breaks
  6. Outputs
    dashboard, Excel, Ask Iris

Key points

  • Works with either door both ways: the first and last sighting on any camera decide the day
  • Time inside = first to last seen, minus the breaks the cameras saw; a missed exit never docks an honest employee
  • Masks the clear glass strip where the lobby camera could see people at their desks, which had cut about 1 in 8 long days short by 2.7 hours
  • Refuses a name when two people look too alike: no name beats a confident wrong one
  • Runs unattended: starts at login, a supervisor restarts it in about 15 s, and the dashboard never says it is recording when it is not
  • Iris never sees staff data to decide what to fetch, only the table layout; it declines off-topic or destructive requests

Results

Speed: where the models run
SetupSeconds per frame
Both models on CPU9.86
Recogniser on iGPU, detector on CPU0.69
Both on iGPU0.31
Picking the score floor from a hand-checked day
FloorNames keptWrong names keptReal people lost
0.2470260
0.3555110
0.404720
0.41 (chosen)4500
Accuracy: face size matters most (17,842 real sightings)
Distance between the eyesShare of sightingsIdentified
0-20 px26%15.8%
20-32 px54%18.1%
32-48 px20%38.9%
48 px +0.3%44.4%

Architecture

CCTV IQ architecture diagram
Technical details
  • The older in/out pairing fully measured only 14% of person-days; the new span-minus-breaks rule gives every day a number and agrees with pairing within 15 minutes 94% of the time
  • A break needs a lobby sighting, then 10+ minutes unseen, then proof of coming back in; days that could hide an early exit get a check flag instead
  • Switching both cameras from H.265 to H.264 fixed 60-73% of frames arriving with a broken bottom band (ping and substream tests had ruled out WiFi)
  • Found and fixed a 9-day silent outage: a thread that crashed quietly, a status flag set before the work started, and nothing watching the process
  • A stalled camera is rebooted over HTTP, and reconnects back off instead of hammering it
  • Iris retries a failed query with the database's own error; every checkable answer in the tests has hand-written SQL beside it
  • Compared four recognition models (antelopev2, AdaFace, buffalo_l, AuraFace): all tied within noise, so camera placement matters more than the model
  • Real phone photos matched about 9.5 points better than AI-edited directory photos
  • Recognition runs in its own thread; the dashboard only reads snapshots, so closing the browser changes nothing
  • Regression tests cover the visit logic, the arrival rules and the ignore-zone geometry
  • computer vision
  • face recognition
  • CCTV analytics
  • attendance system
  • InsightFace
  • OpenVINO
  • edge AI
  • Intel iGPU
  • LLM text-to-SQL
  • AWS Bedrock
  • Claude
  • Python

The code for this project is private, so there is no public link.

All projects