首页/新闻资讯/正文详情

FaceNet人脸考勤系统:从特征提取到SQLite落库的完整实现

发布时间:2026/9/23 22:22:04 来源:云帆数科 栏目:资讯中心
FaceNet人脸考勤系统:从特征提取到SQLite落库的完整实现
简介本资源是一套面向计算机专业本科生的深度学习实战项目聚焦人脸识别考勤系统开发适用于毕业设计、课程设计及期末大作业场景。项目基于FaceNet深度学习算法实现人脸特征提取与比对完整覆盖人脸录入、实时识别、考勤统计、班级/课堂管理及操作日志等核心功能模块代码经严格调试下载解压后可直接运行。压缩包共2000个文件主体为1957个Python源码文件含模型训练、Web接口、GUI界面及数据库交互逻辑辅以11份PDF毕业论文与技术文档、15个配置与说明文本以及少量CSS/JS/HTML前端资源整体大小84.31MB。目前已有697人学习下载资源结构清晰、模块职责分明附带完整工程目录与可复现的实验流程特别适合需快速落地高分毕设、夯实深度学习工程能力的学习者。1. 这不是又一个“调用cv2.VideoCapture就完事”的DemoFaceNet驱动的考勤系统真能跑通人脸录入→特征比对→日志落库全流程你手头那份“基于OpenCV Haar级联LBPH”的毕设代码可能连自己宿舍三个人的脸都分不清——光照一变、角度一偏、戴个口罩识别率直接掉到60%。而这个项目是少数几个在本科毕设尺度下真正把FaceNet嵌进完整业务流的落地案例它不只输出一个相似度分数而是把人脸特征向量存进SQLite、把考勤事件写入带时间戳和班级ID的日志表、把课堂签到状态同步到前端表格。整个流程绕开了TensorFlow 1.x的过时API用PyTorch facenet-pytorch封装了Inception-ResNet v1主干训练好的权重已固化在models/20180402-114759.pt里不用你从零训模型、不用配CUDA环境、不用调参——但凡装得上Python 3.8、有4GB内存、能跑起OpenCV的笔记本就能拉下来跑通全流程。适合正在被导师催进度、被答辩组问“你这识别准不准怎么验证”逼到墙角的本科生也适合想拿真实业务逻辑练手、而不是反复造轮子的转行学习者。2. FaceNet不是黑匣子为什么选它怎么把它从论文公式变成可调试的Python模块2.1 FaceNet的核心价值三元组损失让“同人不同照”比“异人同照”更近很多同学一看到“深度学习人脸识别”第一反应是去GitHub搜face_recognition库——它底层用的是dlib的HOGSVM特征维度低128维、对侧脸/遮挡敏感、泛化性弱。而FaceNet的关键突破在于用三元组损失Triplet Loss重构特征空间强制让同一人的两张不同照片AnchorPositive在嵌入空间距离足够近同时拉开与另一人照片Negative的距离。这种设计让模型学到的是身份不变性特征而非像素级匹配。本项目中face_recognition.py里的FaceNetEncoder类就是这个思想的工程实现# models/facenet_encoder.py import torch import torch.nn as nn from facenet_pytorch import InceptionResnetV1 class FaceNetEncoder(nn.Module): def __init__(self, devicecpu): super().__init__() # 加载预训练权重注意不是ImageNet而是VGGFace2上微调过的 self.resnet InceptionResnetV1(pretrainedvggface2).eval().to(device) self.device device def forward(self, x): # 输入x是[batch, 3, 160, 160]的归一化图像张量 # 输出是[batch, 512]的L2归一化特征向量 x self.resnet(x) return torch.nn.functional.normalize(x, p2, dim1)提示pretrainedvggface2是关键。VGGFace2数据集含2.6M张人脸图、覆盖9K身份比MS-Celeb-1M更侧重姿态多样性。项目里没用casia-webface因为后者在侧脸场景下泛化更差——这是实测踩坑后换的。2.2 特征比对不是简单算余弦阈值怎么定为什么0.4是临界点FaceNet输出的是512维单位向量比对逻辑在core/face_matcher.py中# core/face_matcher.py import numpy as np from scipy.spatial.distance import cosine def match_face(embedding, db_embeddings, threshold0.4): embedding: 当前帧提取的512维向量 (np.array, shape(512,)) db_embeddings: 数据库中所有注册人脸的向量堆叠 (np.array, shape(N, 512)) threshold: 余弦距离阈值越小越严格 返回: (匹配ID, 最小距离, 是否通过) distances [cosine(embedding, db_emb) for db_emb in db_embeddings] min_idx np.argmin(distances) min_dist distances[min_idx] return min_idx, min_dist, min_dist threshold这里threshold0.4不是拍脑袋定的。我用项目自带的test_data/val_set/含30人×5张不同角度照片做了交叉验证阈值0.3 → 误拒率FRR12.7%把同一个人的不同照片判为不同人阈值0.4 → FRR 3.1%误识率FAR0.8%平衡点阈值0.5 → FAR升至5.2%开始出现跨班级误签到。所以0.4是实测收敛值不是默认值。你在config.py里改这个数就能控制考勤严格度——答辩时被问“阈值怎么来的”直接甩这张表。阈值误拒率FRR误识率FAR场景适配建议0.312.7%0.2%高安全场景如实验室门禁0.43.1%0.8%教室考勤推荐0.50.9%5.2%快速通行场景如食堂打卡2.3 人脸检测前置MTCNN为什么比HaarSSD更稳参数怎么调FaceNet只管特征提取前面必须做人脸检测。项目用facenet_pytorch.MTCNN而非OpenCV的Haar或YOLOv5s原因很实在MTCNN是三级级联P-Net→R-Net→O-Net专为人脸设计对小脸60px、侧脸、模糊图像鲁棒性强face_recognition.py里初始化时传了关键参数# core/face_detector.py from facenet_pytorch import MTCNN mtcnn MTCNN( image_size160, # FaceNet输入要求必须160x160 margin0, # 裁剪时是否留边0表示紧贴人脸框 min_face_size20, # 小于20px的人脸直接忽略防噪点 thresholds[0.6, 0.7, 0.7], # 三级网络置信度阈值 factor0.709, # 缩放因子控制金字塔层级密度 devicecpu # 显卡非必需CPU也能跑实测i5-8250U 12fps )min_face_size20是血泪经验教室摄像头通常挂高学生坐后排时人脸在画面中仅30~40px设成10会把噪声当脸框thresholds第三级设0.7而非0.8是为了在保证精度前提下提升召回率——毕竟考勤宁可多抓几个再过滤也不能漏签。3. 毕设最怕“能跑但不闭环”从人脸录入到考勤报表六步打通业务链路3.1 第一步人脸录入不是拍照存图而是生成可比对的Embedding很多毕设卡在“录入”环节学生对着摄像头按一次空格程序存一张jpg完事。本项目app/register.py做了三件事连续采样5帧避免眨眼/闭眼对每帧做MTCNN检测对齐归一化取5帧Embedding的均值作为该生注册特征抗单帧噪声。# app/register.py def register_student(student_id, name, camera_id0): cap cv2.VideoCapture(camera_id) embeddings [] frame_count 0 while frame_count 5: ret, frame cap.read() if not ret: continue # MTCNN返回的是(x,y,w,h)格式的box需转为[x1,y1,x2,y2] boxes, _ mtcnn.detect(frame) if boxes is not None and len(boxes) 0: box boxes[0].astype(int) x1, y1, x2, y2 box[0], box[1], box[2], box[3] face_img frame[y1:y2, x1:x2] # 转PIL并resize到160x160facenet_pytorch要求 pil_img Image.fromarray(cv2.cvtColor(face_img, cv2.COLOR_BGR2RGB)) aligned mtcnn.align_pil(pil_img) # 自动做仿射变换对齐 emb encoder(aligned.unsqueeze(0)) # [1,512] embeddings.append(emb.squeeze().cpu().numpy()) frame_count 1 time.sleep(0.5) # 防止连拍同一姿态 # 存均值向量到SQLite avg_emb np.mean(embeddings, axis0) save_to_db(student_id, name, avg_emb) cap.release()注意mtcnn.align_pil()这行不能省。它会把检测到的人脸做旋转校正基于双眼坐标确保输入FaceNet的图是正脸——否则侧脸特征向量和正脸差异巨大比对必然失败。3.2 第二步考勤逻辑不是“识别成功就打勾”而是带上下文的状态机app/attendance.py里定义了考勤状态机解决三个现实问题防重复签到同一人在同一节课只能签到1次防代签检测到人脸后需持续追踪3秒确认非路过防误触发教室内走动时只对静止超过2秒的人脸生效。# app/attendance.py class AttendanceManager: def __init__(self, class_id): self.class_id class_id self.tracked_faces {} # {track_id: {last_seen: time, stability: int}} self.attended set() # 已签到student_id集合 def process_frame(self, frame): boxes, probs mtcnn.detect(frame) if boxes is None: return for i, (box, prob) in enumerate(zip(boxes, probs)): if prob 0.9: # 置信度不够跳过 continue x1, y1, x2, y2 [int(b) for b in box] face_img frame[y1:y2, x1:x2] pil_img Image.fromarray(cv2.cvtColor(face_img, cv2.COLOR_BGR2RGB)) try: aligned mtcnn.align_pil(pil_img) emb encoder(aligned.unsqueeze(0)).squeeze().cpu().numpy() student_id, dist, matched match_face(emb, db_embeddings) if matched and student_id not in self.attended: # 连续3帧稳定才记录 track_id f{student_id}_{int(time.time())} if track_id not in self.tracked_faces: self.tracked_faces[track_id] {last_seen: time.time(), stability: 1} else: if time.time() - self.tracked_faces[track_id][last_seen] 1.0: self.tracked_faces[track_id][stability] 1 if self.tracked_faces[track_id][stability] 3: self.record_attendance(student_id) self.attended.add(student_id) else: self.tracked_faces[track_id][stability] 1 self.tracked_faces[track_id][last_seen] time.time() except Exception as e: print(fFace processing error: {e})3.3 第三步日志不只是print而是结构化写入SQLite并支持导出所有操作日志存入data/attendance.db表结构如下CREATE TABLE attendance_log ( id INTEGER PRIMARY KEY AUTOINCREMENT, student_id TEXT NOT NULL, student_name TEXT NOT NULL, class_id TEXT NOT NULL, course_name TEXT NOT NULL, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, status TEXT CHECK(status IN (present, late, absent)), device_id TEXT );导出功能在utils/export_report.py里支持按班级/日期生成Excel# utils/export_report.py import pandas as pd import sqlite3 def export_daily_report(date_str, class_id): conn sqlite3.connect(data/attendance.db) query SELECT student_id, student_name, status, timestamp FROM attendance_log WHERE date(timestamp) ? AND class_id ? ORDER BY timestamp df pd.read_sql_query(query, conn, params(date_str, class_id)) df.to_excel(freport_{class_id}_{date_str}.xlsx, indexFalse) conn.close()注意date(timestamp)用的是SQLite内置函数不是Python的datetime避免时区转换错误。导出时自动按时间排序方便辅导员查迟到。4. 避坑那些让毕设答辩当场翻车的6个细节我替你踩过了4.1 现象程序启动报错ModuleNotFoundError: No module named torchvision原因facenet_pytorch依赖特定版本的torchvision而pip install facenet_pytorch默认装最新版与PyTorch 1.10不兼容。解决按requirements.txt顺序安装尤其注意torchvision0.11.2必须与torch1.10.0匹配。执行pip install torch1.10.0cpu torchvision0.11.2cpu -f https://download.pytorch.org/whl/torch_stable.html pip install facenet_pytorch2.5.14.2 现象人脸检测框飘忽不定同一张脸连续帧框位置跳变原因MTCNN默认使用GPU加速但在无CUDA环境下会fallback到CPU而CPU版MTCNN的factor参数对缩放金字塔影响更大导致检测抖动。解决强制指定devicecpu并在core/face_detector.py中增加平滑处理# 在detect前加滤波 if len(boxes) 0: # 取最近3帧的box中心点做移动平均 current_center [(box[0]box[2])/2, (box[1]box[3])/2] self.center_history.append(current_center) if len(self.center_history) 3: self.center_history.pop(0) smoothed_center np.mean(self.center_history, axis0) # 用smoothed_center反推稳定box w, h box[2]-box[0], box[3]-box[1] box [smoothed_center[0]-w/2, smoothed_center[1]-h/2, smoothed_center[0]w/2, smoothed_center[1]h/2]4.3 现象录入人脸后识别总是返回ID为0的“未知用户”原因数据库里student_id字段类型是TEXT但代码里用int(student_id)强转导致字符串001转成整数1查不到对应记录。解决统一用字符串操作。检查core/db_manager.py中所有SQL语句确保WHERE student_id ?的?传入的是字符串不是int。4.4 现象考勤界面卡顿CPU占用率95%以上原因默认每帧都做MTCNN检测FaceNet前向传播而FaceNet在CPU上单帧耗时约300ms。解决启用帧抽样策略。在app/main.py中修改# 原来while True: process_frame() # 改为 frame_skip 3 # 每3帧处理1次 frame_count 0 while True: ret, frame cap.read() if frame_count % frame_skip 0: process_frame(frame) frame_count 14.5 现象导出Excel时报错ValueError: This sheet is too large原因SQLite查询返回上万条记录pandas尝试一次性写入Excel超出Excel行数限制1048576行。解决分页导出。修改export_daily_report函数每次最多取5000条offset 0 while True: df pd.read_sql_query(query LIMIT 5000 OFFSET ?, conn, params(date_str, class_id, offset)) if df.empty: break # 写入Excel不同sheet df.to_excel(writer, sheet_namefpage_{offset//50001}, indexFalse) offset 50004.6 现象答辩演示时摄像头突然黑屏或报错cv2.error: OpenCV(4.5.5) ... libdc1394 error原因Linux系统下OpenCV默认用libdc1394驱动但多数USB摄像头不支持需强制用V4L2。解决在app/main.py中初始化摄像头时指定后端# Linux下强制用V4L2 if os.name posix: cap cv2.VideoCapture(camera_id, cv2.CAP_V4L2) else: cap cv2.VideoCapture(camera_id) # 并设置分辨率避免自动降级 cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)5. 毕设加分项三招让评委眼前一亮——不是炫技而是解决真问题5.1 第一招用混淆矩阵量化识别效果答辩时直接投屏展示别再说“准确率很高”把test_data/val_set/里的30人×5张图跑一遍生成混淆矩阵热力图。代码在utils/evaluate_model.py# utils/evaluate_model.py from sklearn.metrics import confusion_matrix, classification_report import seaborn as sns import matplotlib.pyplot as plt def evaluate_on_valset(): y_true, y_pred [], [] for student_id in os.listdir(test_data/val_set): for img_path in glob(ftest_data/val_set/{student_id}/*.jpg): img Image.open(img_path) aligned mtcnn.align_pil(img) emb encoder(aligned.unsqueeze(0)).squeeze().cpu().numpy() pred_id, _, _ match_face(emb, db_embeddings) y_true.append(int(student_id)) y_pred.append(pred_id) cm confusion_matrix(y_true, y_pred) plt.figure(figsize(10,8)) sns.heatmap(cm, annotTrue, fmtd, cmapBlues) plt.title(Confusion Matrix (30 classes)) plt.ylabel(True Label) plt.xlabel(Predicted Label) plt.savefig(confusion_matrix.png) plt.show()运行后生成的图能直观看出哪几类容易混淆比如戴眼镜vs不戴眼镜的同班同学评委立刻知道你做了严谨验证。5.2 第二招给考勤系统加“可信度评分”让结果可解释FaceNet输出的余弦距离本身是可解释的0.0完全相同1.0完全无关。在app/attendance.py中把match_face()返回的min_dist存入日志表ALTER TABLE attendance_log ADD COLUMN confidence REAL; -- confidence 1 - min_dist值越大越可信前端展示时给每次签到标红/黄/绿confidence 0.8→ ✅ 绿色高可信0.6 confidence 0.8→ ⚠️ 黄色中等建议人工复核confidence 0.6→ ❌ 红色低可信自动标记为“待确认”这样就把黑盒模型变成了白盒决策答辩时说“系统不仅告诉我谁来了还告诉我有多确定。”5.3 第三招用Flask搭轻量Web管理后台摆脱桌面GUI的局限项目自带web/目录用Flask实现班级管理、考勤查询、日志导出。启动命令cd web pip install -r requirements.txt python app.py访问http://localhost:5000即可看到表格展示今日考勤状态含红黄绿标识下拉选择班级/课程实时刷新“导出Excel”按钮一键生成带格式的报表“重录人脸”功能支持现场补录缺勤学生。注意Flask用的是开发服务器正式部署需换Gunicornnginx但毕设演示完全够用。关键是——评委看到Web界面会默认你掌握了前后端协作能力远超单纯写个Tkinter界面的同学。6. 我的毕设血泪教训从“能跑就行”到“可验证、可演示、可答辩”的最后一公里去年帮学弟调试这个项目时他卡在最后三天代码能跑但答辩PPT只有“系统架构图”和“几张截图”被评委连问三个问题就哑火“你测过多少人误识率多少如果两个人长得像怎么办”——其实答案全在项目里只是没人挖出来。后来我们花了两天把test_data/val_set/跑通生成了混淆矩阵把config.py里的THRESHOLD从0.4改成0.35/0.45各跑一遍画出FAR-FRR曲线甚至用手机拍了10段不同光照下的视频统计识别成功率。这些数据塞进PPT答辩时评委眼睛都亮了。所以现在我给自己立了个死规矩任何毕设代码在commit前必须跑通三件事python test/test_registration.py—— 录入5人验证数据库写入正确python test/test_attendance.py --class_id CS2023 --date 2024-06-01—— 模拟考勤检查日志表行数python utils/evaluate_model.py—— 生成混淆矩阵图确认top-1准确率≥92%。这三步加起来不到5分钟但能让你在答辩现场底气十足。不是靠背稿子而是靠数据说话。项目里所有测试脚本、评估工具、配置开关都给你备好了缺的只是动手跑一遍的耐心。希望帮到你。本文还有配套的精品资源点击获取

相关推荐

Dopamine 强化学习框架实验指南:从智能体训练、gin 配置到检查点与自定义扩展
Dopamine 强化学习框架实验指南:从智能体训练、gin 配置到检查点与自定义扩展

机器学习深度学习 【免费下载链接】dopamine Dopamine is a research framework for fast prototyping of reinforcement learning algorithms. 项目地址: https://gitcode.com/gh_mirrors/do/dopamine 点击查看 免费下载 Dopamine 是面向强化学习(RL&… · 2026/9/23 22:21:58

数字广告五大计费模式解析与应用指南
数字广告五大计费模式解析与应用指南

1. 数字广告计费模式全景解析在数字营销领域,广告计费模式的选择直接影响着营销预算的使用效率和最终ROI。作为从业十年的数字营销专家,我见过太多企业因为计费模式选择不当而浪费大量预算。今天我们就来深度剖析五种主流计费模式的内在逻辑和应用场景。… · 2026/9/23 22:21:58

工频变压器与固态变压器核心技术对比分析
工频变压器与固态变压器核心技术对比分析

1. 工频变压器与固态变压器的核心对比基准在电力系统中,变压器作为电能传输和分配的关键设备,其性能直接影响电网的稳定性和效率。传统工频变压器(Frequency Transformer, FT)和固态变压器(Solid State Transformer, S… · 2026/9/23 22:21:52

红外多目标检测数据集:YOLO三格式标签+热感知训练指南
红外多目标检测数据集:YOLO三格式标签+热感知训练指南

简介:本资源是面向计算机视觉初学者与YOLO目标检测实践者的红外多目标检测教学数据集,专为真实场景下的小目标、低对比度检测任务设计,适用于课程实验、毕业设计及算法复现。压缩包共2000个文件,含1986个高质量LabelImg标注的VOC格… · 2026/9/23 23:00:44

中文预训练模型选型指南:大模型、小模型与相似度模型实战对比
中文预训练模型选型指南:大模型、小模型与相似度模型实战对比

简介:这份资源面向中文自然语言处理方向的开发者与研究者,提供一套可直接上手的高质量中文预训练模型集合,覆盖大模型、小模型与语义相似度模型三类需求。大模型在中文任务上达到当前最佳效果,部分任务表现更优;小模型… · 2026/9/23 23:00:37

Loop Engineering 安全写入模式(Safe Write Pattern):让 AI 循环在 MCP 世界中只提议、不越权
Loop Engineering 安全写入模式(Safe Write Pattern):让 AI 循环在 MCP 世界中只提议、不越权

人工智能AI AgentAgent 工作流CLI研发协作AI 技能MCP 服务 【免费下载链接】loop-engineering Practical patterns, starters & CLI tools for loop engineering with AI coding agents. Design systems that prompt and orchestrate agents (inspired by Addy Osmani and … · 2026/9/23 23:00:24

EMQX `$SYS` 保留消息过期机制:修复 StatefulSet 轮换后的陈旧节点标识问题
EMQX `$SYS` 保留消息过期机制:修复 StatefulSet 轮换后的陈旧节点标识问题

后端物联网消息队列通信 【免费下载链接】emqx The most scalable and reliable MQTT broker for AI, IoT, IIoT and connected vehicles 项目地址: https://gitcode.com/gh_mirrors/em/emqx 点击查看 免费下载 导读 本文基于 EMQX 开源仓库的变更记录 fix-16715&… · 2026/9/23 23:00:18

Tyk Gateway 测试框架完全指南:从 TestCase 到端到端 HTTP 测试
Tyk Gateway 测试框架完全指南:从 TestCase 到端到端 HTTP 测试

API网关后端云原生 【免费下载链接】tyk Open Source API and AI Gateway supporting REST, GraphQL, TCP, gRPC and MCP (Model Context Protocol) 项目地址: https://gitcode.com/gh_mirrors/ty/tyk 点击查看 免费下载 Tyk 是一个开源 API 与 AI 网关&#xff0c… · 2026/9/23 23:00:18

接口测试入门与实战:从工具到自动化框架
接口测试入门与实战:从工具到自动化框架

1. 接口测试入门:从零到上手的完整指南刚接触接口测试时,我也曾被各种专业术语和工具搞得晕头转向。直到参与了一个紧急项目,需要在3天内完成50个接口的测试覆盖,才真正掌握了这套高效的工作方法。现在我用最直白的语言&#xff0… · 2026/9/23 23:00:11

3招搞定手机怎么下载微信面试难题实战项目解析
3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧
Win7无线热点配置工具源码解析:解决API失效的3个实战技巧

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧 Win7无线热点配置工具在Win10/11上跑不动?不是你的问题,是版本升级后 API 全变了。很多老项目里的 netsh wlan… · 2026/9/23 0:00:36

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码