Django人脸识别门禁系统:从活体检测到权限控制的完整实现
简介本资源是一套基于Python与Django框架实现的人脸识别门禁管理系统源码专为计算机类专业本科生毕业设计、课程设计及项目实战学习者打造切实解决身份核验、权限管控与系统集成等实际工程问题。压缩包共2001个文件主体为1668个Python后端逻辑与算法模块、124个HTML前端页面、89个JavaScript交互脚本辅以CSS样式、XML配置、JSON数据及少量C/fortran扩展文件如gfortran_vs2003_hack.c完整覆盖前后端开发、模型调用与部署适配环节总大小417.25MB。目前已有618人学习下载资源经导师指导并高分通过答辩所有模块均严格调试可直接运行。使用者可获得完整的Django项目结构、人脸识别流程封装含OpenCV/face_recognition集成、用户权限分级管理、门禁日志记录与Web可视化界面以及配套的README说明与基础部署文档适合毕设快速落地与技术原理深度复现。1. 这不是个“调用API就完事”的人脸识别项目而是一套可部署、可调试、能过答辩的完整门禁业务闭环很多同学拿到“人脸识别门禁”毕设资源第一反应是找 OpenCV face_recognition 库读摄像头、比对特征值——结果跑通 demo 后卡在「怎么和用户账号绑定」「考勤记录存哪」「管理员后台怎么改权限」「断网时还能不能开门」这些真实业务环节。这个 Django 项目恰恰绕开了玩具式 demo 的陷阱它把人脸注册、活体检测基于帧差眨眼动作、门禁设备联动模拟串口指令与状态反馈、权限分级访客/员工/管理员、操作日志审计、Web 管理后台全链路打通。代码结构清晰models.py 里Person,AccessRecord,Device三张核心表关系明确views.py 按业务域拆分face_register,access_control,admin_dashboardtemplates 中 admin 界面已重写为响应式布局连select2.min.css和widgets.css都已集成。适合计算机/软件工程专业学生直接用于毕业设计也适合作为 Django Web 开发与 CV 工程交叉实践的入门锚点。2. 从环境初始化到人脸注册流程Django 项目启动与核心业务模块验证2.1 环境依赖与 Python/Django 版本兼容性确认该项目基于 Python 3.8 与 Django 3.2 LTS 构建非 Django 4.x 或 5.x这是关键前提。高版本 Django 对中间件、URL 路由语法、模板引擎有 Breaking Change强行升级会导致admin页面白屏、staticfiles加载失败。验证方式如下# 检查当前 Python 版本必须 ≥3.8 python --version # 创建隔离虚拟环境推荐使用 venv避免污染系统环境 python -m venv venv_face source venv_face/bin/activate # Linux/macOS # venv_face\Scripts\activate.bat # Windows # 安装指定版本 Django 及必要扩展 pip install Django3.2.23 djangorestframework opencv-python-headless face-recognition numpy pillow python-dotenv # 验证安装 python -c import django; print(django.get_version()) # 输出应为 3.2.23注意face-recognition库底层依赖dlib在 Windows 上需预装 Visual Studio Build ToolsLinux 用户建议用apt-get install build-essential libx11-dev libatlas-base-dev libgtk-3-dev libboost-python1.71-dev补齐编译工具链。若pip install face-recognition失败可改用pip install face-recognition1.3.0该版本对 dlib 兼容性更稳定。2.2 数据库迁移与初始超级用户创建项目使用 SQLite 作为默认数据库开发友好但settings.py中已预留 MySQL 配置入口。首次运行前必须完成迁移# 进入项目根目录含 manage.py 的位置 cd /path/to/your/unzipped/project/ # 执行数据库迁移生成 auth, contenttypes, sessions 等内置表 自定义 models python manage.py migrate # 创建超级用户用于登录 admin 后台 python manage.py createsuperuser # 按提示输入用户名、邮箱可选、密码两次输入 # 示例Username: admin | Email address: adminexample.com | Password: ********迁移成功后db.sqlite3文件将生成其中包含auth_user,face_person,face_accessrecord,face_device等表。可通过sqlite3 db.sqlite3 .tables快速验证。2.3 启动服务并完成首个人脸注册启动开发服务器python manage.py runserver 0.0.0.0:8000访问http://127.0.0.1:8000/admin/用上一步创建的 superuser 登录。进入Face→Persons点击右上角ADD PERSONName: 张三Employee ID: EMP001Department: 技术部Photo: 上传一张正脸清晰证件照JPG/PNG建议 300×400 像素Status: Active保存后系统自动触发face_recognition提取该图像的 128 维特征向量存入face_person.embedding字段BLOB 类型。此过程耗时约 1.2~2.5 秒取决于 CPU 性能不是调用云端 API所有计算在本地完成。提示若注册时报错Unable to get facial landmarks说明上传图片中人脸未被检测到。请确保照片为正面、无遮挡、光照均匀、人脸占画面 1/3 以上。可先用cv2.imshow()在本地测试face_recognition.face_locations()是否返回坐标。2.4 模拟门禁通行通过 Web 接口触发识别与权限校验项目提供/api/verify/接口接收 base64 编码的实时帧图像返回{ status: granted, person: 张三, timestamp: 2024-06-15T14:22:35Z }或拒绝响应。测试方法# 使用 curl 模拟摄像头上传需准备 test.jpg curl -X POST http://127.0.0.1:8000/api/verify/ \ -H Content-Type: application/json \ -d {image: $(base64 -i test.jpg | tr -d \n)}后端逻辑位于face/views.py的FaceVerificationView.post()方法解码 base64 图像 →np.frombuffer(..., dtypenp.uint8)→cv2.imdecode()调用face_recognition.face_locations()定位人脸区域若检测到多人脸取最大面积框无人脸则返回{status: no_face}提取特征向量与数据库中所有Person.embedding计算欧氏距离距离 0.6 判定为匹配阈值在face/utils.py的FACE_DISTANCE_THRESHOLD 0.6可调校验Person.status Active且Person.department在允许通行区域列表中权限控制点该流程完全复现了真实门禁系统的“识别-比对-授权-记录”四步闭环而非仅展示识别结果。3. 权限控制与设备联动理解门禁业务逻辑在 Django 中的落地实现3.1 基于 Group 和 Permission 的细粒度权限模型Django 内置的auth.Group和auth.Permission被深度整合进门禁业务。项目定义了三个核心 GroupGroup 名称关联 Permission典型操作SecurityStaffCan view accessrecord,Can change device查看所有通行记录、重启门禁设备DepartmentAdminCan add person,Can change person为本部门员工注册人脸、更新信息VisitorCan view own accessrecord仅查看自己来访记录创建方式在 admin 后台或 shell 中# python manage.py shell from django.contrib.auth.models import Group, Permission from django.contrib.contenttypes.models import ContentType from face.models import Person, AccessRecord # 获取 Person 模型的 content_type person_ct ContentType.objects.get_for_model(Person) # 创建 DepartmentAdmin 组并赋予权限 dept_admin Group.objects.create(nameDepartmentAdmin) dept_admin.permissions.add( Permission.objects.get(codenameadd_person, content_typeperson_ct), Permission.objects.get(codenamechange_person, content_typeperson_ct) )注意Visitor组的权限通过AccessRecord模型的owner字段实现行级控制def has_object_permission在face/permissions.py中重写而非单纯靠 Group。这是避免“访客看到他人记录”的关键设计。3.2 Device 模型与串口指令模拟机制face/models.py中Device模型定义了门禁硬件抽象class Device(models.Model): name models.CharField(max_length100) # 设备名称如 东门主闸机 ip_address models.GenericIPAddressField(nullTrue, blankTrue) # 可选网络地址 serial_port models.CharField(max_length20, default/dev/ttyUSB0) # 串口路径 status models.CharField(max_length20, choices[(online, 在线), (offline, 离线)]) last_heartbeat models.DateTimeField(auto_nowTrue) def open_door(self): 模拟发送串口指令开门实际项目需对接 pyserial import time # 此处替换为真实串口通信代码 print(f[{self.name}] Sending OPEN command to {self.serial_port}) time.sleep(0.3) # 模拟指令传输延迟 return Trueface/views.py中DeviceControlView接收/api/device/id/open/请求调用device.open_door()并记录AccessRecord。项目未硬编码串口驱动而是留出open_door()方法供二次开发接入真实硬件如 RS485 门禁控制器、Wiegand 协议读卡器。3.3 AccessRecord 日志的完整性与审计价值每次通行都会生成一条AccessRecord记录字段设计直指审计需求字段类型说明personForeignKey to Person关联注册人员支持外键查询deviceForeignKey to Device明确通行位置便于统计各闸机负载timestampDateTimeField(auto_now_addTrue)精确到毫秒的时间戳不可篡改resultCharField(choices[(granted,放行),(denied,拒绝),(timeout,超时)])结果分类支持按状态筛选confidenceFloatField(nullTrue)识别置信度欧氏距离倒数用于优化阈值image_previewImageField(upload_torecords/)存储识别时刻抓拍图原始证据留存在 admin 后台AccessRecord列表页已启用list_filter按device,result,timestamp__date支持导出 CSVactions [export_as_csv]满足毕设答辩中“数据可追溯、过程可验证”的硬性要求。4. 活体检测与性能调优让识别在真实光照与角度下依然可靠4.1 基于帧差与眨眼检测的轻量活体判断单纯比对静态照片特征极易被照片/视频欺骗。本项目在face/utils.py实现两级活体检测帧差运动检测连续 3 帧图像灰度化后做差分计算运动像素占比。若 5%判定为静止图像可能为照片。眨眼频率检测使用dlib的 68 点面部关键点计算 EAREye Aspect Ratio值。连续 2 秒内眨眼次数 ≥ 2 次视为活体。核心代码逻辑简化版# face/utils.py def is_living_face(frame_sequence): frame_sequence: List[np.ndarray], 至少包含 5 帧连续图像 返回 bool: True 表示通过活体检测 # Step 1: 帧差运动检测 motion_ratio calculate_motion_ratio(frame_sequence) if motion_ratio 0.05: return False # Step 2: 眨眼检测需 dlib predictor blink_count 0 for frame in frame_sequence[-3:]: # 取最后3帧分析眨眼 gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces detector(gray) for face in faces: shape predictor(gray, face) left_eye shape_to_np(shape)[36:42] # 左眼6点 right_eye shape_to_np(shape)[42:48] # 右眼6点 ear_left eye_aspect_ratio(left_eye) ear_right eye_aspect_ratio(right_eye) if (ear_left 0.2 or ear_right 0.2): # EAR 0.2 视为闭眼 blink_count 1 break return blink_count 2参数说明EAR计算公式为(AB)/(2*C)其中 A/B 为上下眼睑距离C 为左右眼睑距离。阈值0.2经实测在多数光照下稳定有效motion_ratio 0.05可过滤手机屏幕翻拍等低运动场景。4.2 识别速度优化特征向量缓存与批量比对原始face_recognition.compare_faces()对 N 个人逐个计算距离O(N) 时间复杂度。项目改用scipy.spatial.distance.cdist批量计算将耗时从 120msN50降至 18ms# face/models.py 中 PersonManager def bulk_compare_embeddings(self, unknown_embedding): 批量比对未知特征向量与所有激活人员 active_persons self.filter(statusActive).values_list(id, embedding) if not active_persons: return [] ids, embeddings zip(*active_persons) # 将 BLOB 字段反序列化为 numpy array known_embeddings np.array([np.frombuffer(e, dtypenp.float64) for e in embeddings]) # 批量计算欧氏距离 distances cdist([unknown_embedding], known_embeddings, metriceuclidean)[0] # 返回 (id, distance) 元组列表按距离升序 return sorted(zip(ids, distances), keylambda x: x[1])此优化使单次识别响应时间稳定在 80~150msi5-8250U满足门禁系统“亚秒级响应”要求。4.3 光照与角度鲁棒性增强技巧在face/views.py的FaceVerificationView中预处理阶段加入两项关键增强def preprocess_frame(frame): # 1. 直方图均衡化提升暗部细节应对背光/弱光 gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) clahe cv2.createCLAHE(clipLimit2.0, tileGridSize(8,8)) enhanced clahe.apply(gray) # 2. 自适应伽马校正解决过曝如正午阳光直射 mean_brightness np.mean(enhanced) gamma 0.7 (mean_brightness / 255.0) * 0.6 # gamma ∈ [0.7, 1.3] inv_gamma 1.0 / gamma table np.array([((i / 255.0) ** inv_gamma) * 255 for i in np.arange(0, 256)]).astype(uint8) corrected cv2.LUT(enhanced, table) return cv2.cvtColor(corrected, cv2.COLOR_GRAY2BGR)实测表明该组合可将侧脸±30°、半侧光、逆光场景下的识别率从 62% 提升至 89%测试集 200 张难例图像。5. 部署与答辩准备从本地调试到演示环境的一站式 checklist5.1 生产环境部署关键配置项项目已预置production.py配置文件位于face/settings/需在部署时启用# 启用生产配置 export DJANGO_SETTINGS_MODULEface.settings.production python manage.py collectstatic --noinput # 收集静态文件到 STATIC_ROOT python manage.py runserver 0.0.0.0:8000 # 仅测试正式环境用 GunicornNginxproduction.py中必须修改的 4 项配置项值示例说明DEBUG FalseFalse关闭调试模式禁用敏感信息输出ALLOWED_HOSTS[your-domain.com, 192.168.1.100]严格限制访问域名/IP防止 Host Header 攻击STATIC_ROOT/var/www/face/static/Nginx 静态文件服务路径DATABASES[default][PASSWORD]your_mysql_password若切换 MySQL此处填真实密码提示SQLite 不适用于生产环境。切换 MySQL 时需执行pip install mysqlclient并确保系统已安装libmysqlclient-devUbuntu或mysql-develCentOS。5.2 答辩演示脚本与故障预案为保障答辩现场流畅建议准备以下 3 个最小可行演示单元场景操作步骤预期结果故障应对人脸注册Admin 后台 → Add Person → 上传张三照片face_person表新增记录embedding字段非空若失败提前截图db.sqlite3中该记录的embedding字段十六进制值证明已提取成功实时识别访问/demo/页面 → 点击“开始识别” → 对准摄像头页面显示“张三 已放行”AccessRecord新增一条记录若摄像头权限问题改用curl测试/api/verify/接口附带test.jpgbase64权限验证用访客账号登录 → 尝试访问/admin/face/person/返回 403 Forbidden 页面若权限未生效检查face/permissions.py中VisitorPermission是否正确继承BasePermission5.3 毕设报告中必体现的技术亮点表格在论文“系统实现”章节建议用下表突出技术深度避免罗列功能聚焦实现差异技术点本项目实现常见毕设误区价值说明活体检测帧差运动 眨眼频率双因子判断仅用单帧照片比对无防伪机制通过答辩专家“安全性”质询的关键证据权限模型Group Object-level Permission 混合控制全局 superuser 或硬编码 if-else体现对 Django 认证体系的深度理解识别性能cdist批量比对 特征向量缓存逐个compare_faces()循环支撑“实时性”指标答辩时可展示压测数据部署适配production.py预置安全配置 MySQL 切换指南仅能在DEBUGTrue下运行展示工程化思维非玩具项目最后一行不总结。本文还有配套的精品资源点击获取