A FastAPI application for enrolling known faces and performing live recognition via the browser webcam. Simple UI: capture once to enroll a name, then start live recognition to see bounding boxes, names, and scores.
- Webcam enrollment: type a name, capture one frame; auto-creates the person and stores the embedding
- Live recognition: in-browser webcam streaming over WebSocket; shows boxes, names, and scores
- No photo storage by default: only normalized embeddings are saved; images are not written to disk unless you opt in
- Clean architecture: FastAPI, SQLAlchemy (SQLite), modular services and routers
- OpenCV default backend: works out-of-the-box on Windows; optional upgrade path to InsightFace
face-recognition/
├─ app/
│ ├─ __init__.py
│ ├─ main.py # App factory, services, routers, static
│ ├─ config.py # Settings via pydantic-settings
│ ├─ database.py # SQLAlchemy engine/session
│ ├─ models.py # Person, FaceEmbedding
│ ├─ schemas.py # Pydantic models
│ ├─ utils/
│ │ └─ image_utils.py # Image I/O and cropping
│ ├─ services/
│ │ ├─ face_service.py # Detection + embeddings (OpenCV default)
│ │ └─ recognition_service.py# Enrollment and matching
│ └─ api/
│ ├─ routes_persons.py # Create/list persons
│ ├─ routes_faces.py # Enroll images to a person
│ └─ routes_recognition.py # Single-image recognition
│ └─ routes_realtime.py # WebSocket for live recognition
├─ frontend/
│ ├─ index.html # Minimal UI
│ └─ app.js # Webcam enrollment + live overlay
├─ tests/
│ ├─ conftest.py # Mocked FaceService for tests
│ └─ test_api.py # Basic API flow test
├─ data/
│ └─ images/ # (optional) image storage if enabled
├─ .env.example # Sample configuration
├─ .gitignore # Excludes env, data, keys, logs, caches
├─ requirements.txt
└─ README.md
- Create a virtual environment and install dependencies
- Git Bash (Windows):
python -m venv .venv
source .venv/Scripts/activate
pip install --upgrade pip
pip install -r requirements.txt
- PowerShell (Windows):
python -m venv .venv
. .\.venv\Scripts\Activate.ps1
pip install --upgrade pip
pip install -r requirements.txt
- Run the server
python -m uvicorn app.main:app --reload
Open the app at http://127.0.0.1:8000
.
- Enroll from webcam: Enter a name and click “Capture & Enroll”. If the person does not exist, the app creates it and saves an embedding computed from the frame.
- Live Recognition: Click “Start Live”. The page streams frames to the server and overlays bounding boxes with the best match and score.
- POST
/api/persons
→ create a person:{ name, metadata? }
- GET
/api/persons
→ list persons (with face counts) - POST
/api/persons/{person_id}/faces
(multipartfiles
) → enroll one or more face images for a person - POST
/api/recognize
(multipartfile
) → detect and match faces in a single photo - WS
/ws/recognize?threshold=0.35
→ stream JPEG frames (binary) to receive per-frame recognition results
OpenAPI docs: http://127.0.0.1:8000/docs
All settings can be set via environment variables or a .env
file.
APP_DATABASE_URL
(default:sqlite:///./app.db
)APP_DATA_DIR
(default:data
)APP_IMAGES_DIR
(default:data/images
)APP_STORE_IMAGES
(default:false
) — iftrue
, saves original photos and face crops to diskAPP_EMBEDDING_BACKEND
(default:opencv
) —opencv
|insightface
|mock
APP_RECOGNITION_THRESHOLD
(default:0.35
) — cosine similarity threshold for a matchAPP_INSIGHTFACE_PROVIDER
(default:CPUExecutionProvider
) — for ONNXRuntime when using InsightFaceAPP_LOG_LEVEL
(default:info
)
Example .env
:
APP_DATABASE_URL=sqlite:///./app.db
APP_DATA_DIR=data
APP_IMAGES_DIR=data/images
APP_STORE_IMAGES=false
APP_EMBEDDING_BACKEND=opencv
APP_RECOGNITION_THRESHOLD=0.35
APP_INSIGHTFACE_PROVIDER=CPUExecutionProvider
APP_LOG_LEVEL=info
- The browser captures frames and sends them as JPEG binaries over WebSocket.
- The server detects faces and computes embeddings (OpenCV default uses Haar cascade + simple embedding; deterministic and fast but less accurate than deep models).
- All known face embeddings live in SQLite; recognition is a cosine similarity search with a simple max-score match.
- No photo storage by default: only embeddings are saved. Set
APP_STORE_IMAGES=true
to retain photos/crops. .gitignore
excludesdata/
and.env
to avoid committing private data.- For production, run behind HTTPS, restrict CORS, and harden the deployment (process manager, logging, backups, secure secrets storage).
pytest -q
Tests mock the embedding service to avoid heavy model downloads.
- You can try
APP_EMBEDDING_BACKEND=insightface
for deep embeddings. This requires installinginsightface
and system build tools on Windows.- Install:
pip install insightface
- Note: Windows may require Microsoft Visual C++ Build Tools; first run downloads models via ONNXRuntime.
- Install:
- Alternative approaches include prebuilt face recognition libs or hosted embedding APIs.
- “uvicorn: command not found” in Git Bash: run via Python module:
python -m uvicorn app.main:app --reload
- Camera permission: allow access in the browser, and ensure no other app is using the webcam.
- No matches: enroll 2–3 captures of the same person under similar lighting, and try thresholds between
0.30
–0.45
.
This project is intended as a starting point. Accuracy depends on the embedding backend and camera conditions. For multi-camera dashboards, GPU acceleration, or watchlists/alerts, extend the services and UI as needed.