尚未收集儲存庫資訊。
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
Local face-recognition attendance system - OpenCV LBPH with liveness checks, fairness benchmarking, and a Flask dashboard. No face data leaves the machine.
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗A local attendance system: OpenCV reads the webcam, recognises enrolled faces, and logs each one to SQLite. Nothing leaves the machine.
Tracked live, judged live. The mesh is MediaPipe's; the instruction, checklist
and priority chain are this project's pipeline/guidance.py — fourteen rules in
a fixed order, of which only the first to fire is shown, so a person gets one
thing to do instead of a list. tools/build_static.py refuses to publish the
JavaScript if it disagrees with the Python.
The recording handed a still photograph to the browser as if it were a camera, and paints the frame over after the measurements are read — so the GIF carries the tracking and nobody's face. Open the page and it is your own camera; no frame leaves the tab.
Neither page recognises anyone. That needs a 328 MB trainer.yml and a
camera the server owns; a tab gets detection, landmarks and guidance. MediaPipe
is not this project's detector either — the app uses YuNet or Haar and OpenCV's
68-point LBF model — so the camera page labels every input as the same
measurement, an approximation, or not measured at all.
Read the full write-up →
— the 97,698-face benchmark, where recognition stops working, and every bug this
has had. (Or docs/index.html locally.)
pip install -r requirements.txt
python -m cli.fetch_models # ~196 MB of pretrained weights, once
python app.py # http://127.0.0.1:5001
The camera is opened by the server, not the browser, so this runs on the
machine it is plugged into — which is why the demos cover only the arithmetic.
Don't skip the middle line: attendance works without those weights, but
traits, liveness, quality scoring and SFace identification degrade quietly,
which looks like the app being broken rather than incomplete.
GET /api/models names the missing ones.
Then register a person and capture ~30 samples. Attendance is decided by SFace
embeddings against a calibrated threshold, with LBPH only as the fallback when
the SFace weights are missing; recognised faces that pass the liveness check
get one attendance row per person per day, recording which recogniser made it. The same
on the CLI — cli.register_user, cli.attendance, cli.view_report — and
cli.seed_demo --people 40 enrolls from LFW to try recognition without
registering anyone. Every feature, with the endpoint and command behind it, is
listed on the camera page.
All 97,698 images of FairFace. Full results in BENCHMARK.md.
analysis/calibration.py takes a gallery size
instead of returning a constant.Effectiveness. 40 enrolled, held-out LFW images: 92.9% correct (223/240), 6.7% rejected as unknown, 0.4% misidentified, 100% impostor rejection over 300 non-enrolled faces. The failure mode is the safe one.
Operating range. Detection holds at 100% throughout; recognition degrades.
| Condition | Holds until | Breaks at |
|---|---|---|
| Distance (downscale) | 0.25× (83%) | 0.15× (23%) |
| Motion blur | 9 px (83%) | 13 px (47%) |
| Lighting (gamma 0.4–2.2) | no measurable loss | — |
| In-plane rotation | 15° (80%) | 30° (37%) |
| JPEG compression | q20 (83%) | q10 (77%) |
A tilted camera costs more than a dim room.
app.py the Flask entry point, and the only module left in the root
core/ paths, vision constants, the database, the model loaders
pipeline/ the capture path: camera, traits, landmarks, liveness,
guidance, recognition, training
analysis/ enrollment quality, threshold sweeps, calibration, fairness
cli/ the command-line entry points
tools/ developer scripts, corpus benchmarks, the demo build
Thirty-one modules used to sit flat in the root. tests/layout.py writes the
grouping down once, and the structural tests read it from there.
notes/ holds the long-form write-ups — BENCHMARK.md, CODE_AUDIT.md — and
CONTRIBUTING.md is in .github/, which is where GitHub looks for it.
dataset/ and trainer.yml as biometric data — don't
commit them, and delete a person's folder and retrain if they ask to be
removed.pytest -q
1,053 tests, 100% of 4,498 statements, needing no webcam, no weights and no corpus. Tests that need a real face use a sample frame if one is present and skip rather than asserting against a synthetic one, because a face a detector accepts cannot be faked convincingly enough to be evidence.
MIT — see CONTRIBUTING.md for setup and conventions.