Documentation

Everything you need to install, configure, and run DBFComp.

Overview

DBFComp is a self-hosted facial-recognition system for NVR security cameras. When a camera detects motion, the NVR pushes an event to DBFComp, which pulls the frame over RTSP, detects and recognizes the face against your enrolled database, and posts a Discord alert with an enhanced close-up.

The recognition pipeline is pluggable: a MODEL_TIER selects the model stack, and everything runs through ONNX Runtime so it's GPU-accelerated on Apple Silicon (CoreML) and Windows + NVIDIA (CUDA).

Requirements

Install

# clone, then create a virtualenv
python3 -m venv .venv
source .venv/bin/activate            # Windows: .venv\Scripts\activate
pip install -U pip
pip install -r requirements.txt

On Windows + NVIDIA, swap onnxruntime for onnxruntime-gpu (with a matching CUDA toolkit + cuDNN) and leave ONNX_PROVIDERS blank to auto-select CUDA.

First-time setup

python face_watch.py setup           # interactive wizard → writes .env
python face_watch.py doctor          # verify env, ffmpeg, models, DB, Discord

doctor tells you exactly what's missing for your active tier — handy when bringing up a second machine.

Model tiers

Set MODEL_TIER to choose the recognition stack:

TierRecognizerDetectorNotes
liteEdgeFace-SYuNetTiny/fast, CPU-friendly (no InsightFace)
standardglintr100det_10gProven default; age/gender
maxAdaFace IR-101det_10gStrongest; needs a GPU

lite and max recognizers are exported to ONNX once (PyTorch is only needed for that step — the runtime stays torch-free):

python3 -m venv .venv-export
.venv-export/bin/pip install -r scripts/requirements-export.txt
.venv-export/bin/python scripts/export_onnx.py all     # → models/recog/*.onnx
python face_watch.py fetch-models                       # YuNet / GFPGAN / MiniFASNet

Switching the recognizer changes the embedding space, so re-embed your enrolled faces:

# set MODEL_TIER (or RECOG_MODEL) in .env, then:
python face_watch.py rebuild-db

GFPGAN restoration (RESTORE, on by default for standard/max) cleans up the alert close-up into a sharp, aligned face.

Configuration

All settings live in .env (generated by setup). Highlights:

KeyMeaning
MODEL_TIERlite / standard / max
ALERT_MODEunknown_only / known_and_unknown / all
SIMILARITY_THRESHOLDCosine match threshold (glintr100; default 0.4)
RECOG_THRESHOLDOverride threshold for EdgeFace/AdaFace
RESTOREGFPGAN restoration on/off
LIVENESSMiniFASNet anti-spoof annotation (experimental, off)
ONNX_PROVIDERSBlank = auto (CoreML on Mac, CUDA on Windows)
FFMPEG_PATHBlank = resolve from PATH
DISCORD_*Bot token, guild id, alert channels / users

Discord setup

  1. Create a bot at the Developer Portal and copy its token.
  2. Invite it to your server with the bot + applications.commands scopes (a guild install — user-installs can't send alerts).
  3. Enable Developer Mode in Discord, then copy your channel and user ids.
  4. Put them in .env: DISCORD_BOT_TOKEN, DISCORD_GUILD_ID, DISCORD_ALERT_CHANNEL_IDS, DISCORD_ALERT_USER_IDS.

Slash commands (guild-synced on startup):

/reviewDashboard: today's faces + action buttons
/people · /pendingList enrolled people / faces awaiting a name
/enroll name <photo>Enroll a person from an attached photo
/name · /ignoreName or skip a reviewed face
/rename · /removeEdit the database
/rebuild_db · /test · /helpRe-embed after a tier switch · system check · help

When a stranger recurs, DBFComp DMs you a montage with Name / Ignore buttons.

CLI commands

python face_watch.py setup            # write .env
python face_watch.py doctor           # health check
python face_watch.py fetch-models     # download models for the active tier
python face_watch.py list             # enrolled people
python face_watch.py watch            # run the watcher (main loop)
python face_watch.py rebuild-db       # re-embed data/people/ into the active model

Plus enroll, remove, import, cluster, label, folders, split, review, and capture for managing the recognition database.

Enrolling people

python face_watch.py enroll --name "Dad" --photos ./photos/dad/
python face_watch.py enroll --name "Mom" --photo ./photos/mom.jpg
python face_watch.py list

Or enroll straight from Discord with /enroll and a photo attachment. The watcher hot-reloads the database, so new enrollments take effect without a restart.

Run as a service

macOS (launchd): copy com.facewatch.plist into ~/Library/LaunchAgents/ and load it:

cp com.facewatch.plist ~/Library/LaunchAgents/
launchctl load -w ~/Library/LaunchAgents/com.facewatch.plist
launchctl kickstart -k "gui/$(id -u)/com.facewatch"   # restart after changes

Windows: run it on login with NSSM (a real service that restarts on crash) or Task Scheduler:

nssm install dbfcomp "C:\path\.venv\Scripts\python.exe" "C:\path\face_watch.py" watch
nssm set dbfcomp AppDirectory "C:\path"
nssm start dbfcomp

Troubleshooting

Start with doctor — it reports the active tier and flags anything missing (model files, an empty DB after a tier switch, ffmpeg, providers, Discord config):

python face_watch.py doctor

DBFComp · Database Facial Comparison — github.com/LAOUUUUU/face-watch