news 2026/10/1 4:55:19

Python人脸识别考勤系统课设:OpenCV+SQLite完整源码与避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python人脸识别考勤系统课设:OpenCV+SQLite完整源码与避坑指南

简介:本资源为基于人脸识别的学生考勤签到管理系统完整课程设计包,面向计算机、人工智能、通信、物联网等专业在校学生与教师,可用于课程设计、毕业设计、大作业或项目立项演示。包内共160个文件,以52个py源码与78个pyc编译文件为核心,辅以mp4运行演示视频、docx课设报告、pkl模型文件、xlsx数据表、db数据库及xml人脸定位文件等,压缩包约10.16MB。系统涵盖人脸录入、训练与识别签到、签到签退、哈希加密等模块,服务端与客户端分离,并附有LSTM用户画像与考勤数据分析的完整研究方案。已有270人学习下载。读者可获得可稳定运行的源码、实操录屏、结构清晰的课设报告与排错说明,便于快速理解人脸识别考勤的工程实现,并在此基础上进行二次开发与功能扩展。

1. 从一份课设压缩包说起:人脸识别考勤系统能跑成什么样

课程设计季一到,计算机相关专业的同学最头疼的往往不是写报告,而是找一个「代码完整、功能验证过、还能讲清楚原理」的项目。这份基于人脸识别的学生考勤签到管理系统,就是冲着这个场景来的:Python 源码、运行视频、课设报告三件套打包在一起,客户端负责摄像头采集与人脸识别签到,服务端负责接收数据、落库和统计展示。它适合计科、人工智能、物联网等方向的学生做课设、毕设或大作业,也适合刚入门想拿一个完整 C/S 架构项目练手的开发者。需要先说明的是,项目里人脸识别用的是轻量预训练模型,定位人脸的能力比重量级方案弱一些,但换来的是在普通笔记本上也能跑起来的运行速度,这个取舍后面会细讲。

2. 拆开压缩包:目录结构、技术栈与运行前置条件

2.1 文件清单与各文件职责

解压之后先别急着双击运行,花两分钟把目录看一遍,能省掉后面一半的报错排查时间。从项目正文给出的打包情况看,核心文件分布大致如下:

文件/目录作用备注
client.py客户端主程序摄像头采集、人脸识别、签到签退入口
main.py服务端主程序监听端口、接收数据、写库
testDB.dbSQLite 数据库文件存储学生信息与考勤记录
haarcascade_frontalface_default.xml人脸定位级联分类器必须放到 client 端根目录
pip.inipip 镜像配置加速依赖安装
课程设计报告.docx课设报告含目录、实验分析、结论
项目说明.md运行说明端口、路径等关键提示

这里有个血泪经验:haarcascade_frontalface_default.xml放在DATASource目录里,但程序运行时是从 client 端根目录找它的。很多人第一次跑报「无法定位人脸」,不是摄像头坏了,是这个 xml 没挪位置。

2.2 技术栈与依赖环境

项目是典型的 Python C/S 架构,客户端和服务端通过本机地址127.0.0.1、端口12345通信。人脸识别部分走的是 OpenCV 的传统路线:Haar 级联做人脸定位,再提取特征生成 yml 模型文件,识别时调用 yml 特征库做快速比对。数据库用 SQLite,单文件testDB.db,不需要额外装数据库服务,这对课设环境很友好。

依赖安装建议先看pip.ini,里面通常配好了国内镜像源。如果没配,手动指定一下:

pip install opencv-python opencv-contrib-python numpy pillow -i https://pypi.tuna.tsinghua.edu.cn/simple

opencv-contrib-python不能省,人脸识别相关的face模块在 contrib 包里,只装opencv-python会在cv2.face处报AttributeError。参数上,-i后面跟镜像地址,网络正常的话几十秒就能装完。

提示:项目路径和项目名不要用中文,解压后重命名为英文再运行,否则 OpenCV 读文件时可能出现解析不了的错误。

2.3 启动顺序与端口检查

启动顺序不能反:先起服务端,再起客户端。服务端main.py会绑定12345端口,如果这个端口被占用,客户端连不上会直接报连接错误。常见占用源是某些网盘客户端,项目说明里专门提到「如果出现报错请关闭阿里云盘」,就是这个原因。

# 先启动服务端 python main.py # 另开一个终端启动客户端 python client.py

服务端启动后不要关那个终端窗口,它需要一直监听。客户端启动后会调摄像头,第一次运行系统会弹权限申请,允许即可。如果摄像头被其他程序占用(比如视频会议软件),客户端会黑屏或报can't open camera,关掉占用程序再试。

3. 人脸录入、训练与签到:三个核心功能的实现链路

3.1 人脸录入:采集多少张、怎么采才有效

人脸录入是整个系统的数据源头,采得好不好直接决定后面识别的准确率。项目里录入功能会调用摄像头,对同一个人采集多张人脸图像,存到指定目录并绑定学号或姓名。常见做法是采集 20 到 30 张,覆盖正脸、轻微左右偏转、戴眼镜和不戴眼镜的情况。

采集时有两个参数值得注意:一是采集间隔,不要连续狂拍,每张之间隔个零点几秒,让脸有轻微移动,增加样本多样性;二是光照,尽量在均匀光线下采,背光或侧光太强会让 Haar 定位失败,采到的图里根本没有脸,训练出来就是废模型。

import cv2 # 加载人脸定位分类器,路径按实际放置位置调整 face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') cam = cv2.VideoCapture(0) # 0 表示默认摄像头 count = 0 while count < 30: ret, frame = cam.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 转灰度,Haar 只吃灰度图 faces = face_cascade.detectMultiScale(gray, 1.3, 5) # 缩放系数1.3,最小邻居数5 for (x, y, w, h) in faces: count += 1 cv2.imwrite(f'data/User.{count}.jpg', gray[y:y+h, x:x+w]) # 只存人脸区域 cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2) cv2.imshow('capture', frame) if cv2.waitKey(100) & 0xFF == 27: # 按 ESC 提前退出 break cam.release() cv2.destroyAllWindows()

detectMultiScale的两个关键参数:scaleFactor=1.3表示每次图像尺寸缩小 1.3 倍来搜索人脸,值越小搜得越细但越慢;minNeighbors=5表示一个候选框周围要有 5 个邻居才确认是人脸,调高能减少误检,调低能减少漏检。采完图后建议人工翻一遍,把明显不是脸的图删掉,这一步偷懒后面识别就会翻车。

3.2 人脸训练:yml 模型是怎么生成的

录入的是一张张 jpg,训练要做的是把这些图喂给识别器,生成一个 yml 特征库文件。项目用的是特征提取方法,常见实现是 LBPH(局部二值模式直方图)识别器,它对光照变化有一定鲁棒性,适合课设这种小样本场景。

import cv2 import numpy as np import os recognizer = cv2.face.LBPHFaceRecognizer_create() detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') def get_images_and_labels(path): image_paths = [os.path.join(path, f) for f in os.listdir(path)] faces = [] ids = [] for image_path in image_paths: gray = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE) # 文件名格式 User.1.1.jpg,取第二段作为标签 ID id = int(os.path.split(image_path)[-1].split('.')[1]) faces.append(gray) ids.append(id) return faces, np.array(ids) faces, ids = get_images_and_labels('data') recognizer.train(faces, ids) # 训练 recognizer.write('trainer/trainer.yml') # 生成 yml 模型 print(f'训练完成,共 {len(faces)} 张样本')

LBPHFaceRecognizer_create()创建识别器,train()接收人脸数组和对应标签数组,write()把模型落盘成 yml。标签 ID 从文件名里解析,所以录入时文件名格式必须统一,否则训练出来的标签是乱的,识别时全对不上号。训练完成后,识别阶段用recognizer.predict()返回标签和置信度,置信度越低表示越像,一般低于 50 可以认为是同一个人,具体阈值要按自己采集的样本调。

3.3 签到与签退:数据怎么从客户端流到数据库

签到签退是业务层逻辑。客户端识别出人脸后,拿到对应的学生 ID,把签到时间、状态打包,通过 socket 发给服务端,服务端写进testDB.db。项目里签到和签退是两个独立功能,通常按时间段区分:上午到课算签到,下课离开算签退。

import socket import json import datetime def send_checkin(student_id, action): payload = { 'student_id': student_id, 'action': action, # 'checkin' 或 'checkout' 'time': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') } s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1', 12345)) # 地址和端口与服务端一致 s.send(json.dumps(payload).encode('utf-8')) resp = s.recv(1024).decode('utf-8') s.close() return resp

这里用 JSON 做序列化,比直接拼字符串稳,字段清晰也好扩展。action字段区分签到签退,服务端按这个字段决定写哪张表或哪个状态位。哈希加密功能用在学生密码或敏感字段上,常见做法是hashlib.sha256加盐,避免明文存库。socket 通信要注意粘包问题,课设规模下数据量小,一般不会触发,但如果后面扩展成多用户并发,就得加长度头或分隔符来切分消息边界。

4. 避坑与排查:打包失败功能与运行报错怎么处理

4.1 教师端刷新查看功能失效

现象:教师端点刷新没反应,或者直接抛异常退出。原因是这个功能用了并行库,打包成 exe 后并行库的进程创建机制和打包环境冲突,子进程起不来。解决方式是别用打包好的 exe,直接跑源码python main.py,源码环境下并行库正常。如果必须打包,把并行部分改成串行或线程池,牺牲一点速度换稳定。

4.2 多用户签到在部分电脑上跑不起来

现象:同一份代码,有的电脑能多用户同时签到,有的直接卡死或丢消息。原因是消息队列在不同系统上的实现依赖有差异,项目说明里也写了「原因尚未明确」。解决方式是课设演示时用单用户串行签到,或者把消息队列换成基于 socket 的简单请求-响应模式,一个请求处理完再处理下一个,虽然并发能力弱,但至少不会玄学崩溃。

4.3 用户画像功能显示违规字符

现象:历次签到时间通过 socket 传输后,界面上出现乱码或违规字符。原因是编码不一致,发送端和接收端的解码方式没对齐,或者时间字符串里混入了不可见字符。解决方式是在发送前统一encode('utf-8'),接收后统一decode('utf-8'),并在写库前对字符串做一次清洗,过滤掉非打印字符。

4.4 打包后启动和运行明显变慢

现象:源码跑得好好的,打包成 exe 后启动要等十几秒,识别也变卡。原因是打包工具把整个 Python 解释器和依赖都塞进 exe,启动时要解压到临时目录,加上项目本身多用户连接的实验数据是在源码环境测的,打包后环境变了,数据自然对不上。解决方式是演示和实验数据采集都用源码环境,exe 只作为分发备份,不作为性能参考。

4.5 端口被占用导致连接失败

现象:客户端报连接拒绝或超时。原因是12345端口被其他程序占了,网盘客户端是常见嫌疑。解决方式是先查端口占用,Windows 下用netstat -ano | findstr 12345找到 PID,再决定是关程序还是改端口。改端口的话,客户端和服务端两边的端口号要同步改,只改一边照样连不上。

5. 从能跑到好用:阈值调优与二次开发的一点技巧

把系统跑起来只是第一步,真正让它在答辩或演示时不出丑,靠的是几个细节调优。先说识别阈值,LBPH 的predict()返回的置信度不是概率,是距离,值越小越像。默认没有固定阈值,你得自己试:拿同一个人不同角度的图测,记录置信度分布,再拿不同人的图测,找一个能把两者分开的临界值。我一般会写个小脚本批量跑一遍,把置信度打出来看分布,而不是凭感觉设一个 50 就完事。

# 批量测试置信度分布,帮助确定阈值 import cv2 recognizer = cv2.face.LBPHFaceRecognizer_create() recognizer.read('trainer/trainer.yml') test_img = cv2.imread('test/someone.jpg', cv2.IMREAD_GRAYSCALE) label, confidence = recognizer.predict(test_img) print(f'预测标签: {label}, 置信度: {confidence:.2f}') # 置信度低于阈值判为同一人,高于阈值判为陌生人

再说二次开发。项目本身留了不少扩展口子:签到数据已经在testDB.db里,想加考勤率统计,直接写 SQL 查就行;想加人脸识别门禁联动,把签到成功后的 socket 消息再转发一路给门禁控制端即可。用户画像那块用了 LSTM 做签到预测,如果你不想碰深度学习,换成简单的统计方法——比如按学生历史签到时间算个均值方差,超过阈值就标异常——效果未必差,还省了训练时间。

最后说一个我自己的习惯:每次改完代码,先不急着接摄像头,用几张本地图片跑一遍识别流程,确认模型加载、标签解析、数据库写入这三步都通,再接硬件。这样出问题时能快速定位是算法层还是硬件层。从那以后我每次交付这类课设项目,都强制走一遍「本地图测试 → 摄像头测试 → 多用户测试」的流程,省得在演示现场手忙脚乱。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/1 4:55:19

Spring Boot健身管理APP毕设全拆解:从源码到答辩实战指南

最近接到好几个读者私信&#xff0c;都是拿《基于Spring Boot的健身管理APP设计与实现》这个题目来问的。有些是准备开题&#xff0c;有些是代码跑不起来&#xff0c;还有几个是答辩前找我要“速成补丁”的。说实话&#xff0c;这个题目在计算机毕业设计里属于热度非常高的那一…

作者头像 李华
网站建设 2026/10/1 4:54:32

RuoYi框架安全攻防:从漏洞挖掘到加固实践

这套系统有个老版本&#xff0c;部署特别多&#xff0c;所以挖这类目标的时候第一件事就是判断版本。框架本身一直在更新&#xff0c;但真正跑在公网上的&#xff0c;大量还是停留在两三年以前的版本&#xff0c;那批版本里的问题基本是明牌。2.1 先看懂攻击链路&#xff1a;请…

作者头像 李华
网站建设 2026/10/1 4:54:32

EEG脑电信号分类技术体系全解析:从传统方法到深度学习实战

1. 为什么EEG分类值得单独写一篇体系化梳理脑电信号分类这个方向&#xff0c;我前前后后跟了快六年&#xff0c;从最早拿SVM加手工特征跑二分类&#xff0c;到后来用CNN做端到端&#xff0c;再到现在折腾图神经网络建模电极间拓扑关系&#xff0c;踩过的坑比跑通的实验多得多。…

作者头像 李华
网站建设 2026/10/1 4:54:32

基于CNN的网络入侵检测实战:从特征编码到模型部署

简介&#xff1a;基于卷积神经网络实现网络入侵检测的完整项目代码包&#xff0c;面向希望掌握深度学习与网络安全结合应用的小白和进阶学习者&#xff0c;适合用于毕业设计、课程设计或工程实训。包内提供数据预处理脚本、一层全连接层对照代码和CNN主程序&#xff0c;配套KDD…

作者头像 李华
网站建设 2026/10/1 4:54:31

并行归约、区间贪心与树状数组:execution环境下的算法工程实践

最近在做一套综合性的算法与计算优化练习,项目标题是“execution并行归约|区间贪心|树状数组”。乍一看这三个词像是从不同教科书里硬凑出来的——并行归约是高性能计算里的经典操作,区间贪心是算法设计课的常客,树状数组则是竞赛选手人手一份的数据结构。但把它们放到同一个执…

作者头像 李华