
本文针对基于OpenCV和face_recognition库构建的人脸识别考勤系统,解决了在摄像头持续识别人脸时,重复将考勤记录写入CSV文件的问题。通过调整代码逻辑,确保每个人只记录一次考勤信息,并提供优化建议,提高程序效率。
在构建人脸识别考勤系统时,一个常见的挑战是避免重复记录考勤信息。以下将详细介绍如何修改代码,确保每个人只记录一次考勤,并提供一些优化建议。
问题分析
原始代码在主循环中,每次检测到人脸匹配时,都会调用 markAttendance 函数。由于摄像头帧率很高,即使人脸只出现一次,也会被多次检测到,导致重复写入 CSV 文件。
解决方案
核心思路是:在将姓名写入文件之前,先检查该姓名是否已经存在于已记录的姓名列表中。如果存在,则跳过写入操作;否则,才进行写入。以下是修改后的 markAttendance 函数:
from datetime import datetime
def markAttendance(name):
with open('Attendance.csv', 'r+') as f:
myDataList = f.readlines()
nameList = []
for line in myDataList:
entry = line.split(',')
nameList.append(entry[0])
if name not in nameList:
now = datetime.now()
dtString = now.strftime('%H:%M:%S')
f.writelines(f'\n{name},{dtString}')代码解释:
优化建议
虽然上述代码可以解决重复写入的问题,但每次调用 markAttendance 函数时都读取整个 CSV 文件效率较低。可以进行以下优化:
以下是优化后的代码示例:
def readNames():
try:
with open('Attendance.csv', 'r') as f:
nameList = [line.split(',')[0] for line in f]
except FileNotFoundError:
# 如果文件不存在,创建一个空文件并返回一个空列表
open('Attendance.csv', 'w').close()
nameList = []
return nameList
def markAttendance(name, nameList):
if name not in nameList:
nameList.append(name)
with open('Attendance.csv', 'a') as f:
dt = datetime.now().strftime('%H:%M:%S')
f.writelines(f'\n{name},{dt}')
# --- 主程序 ---
nameList = readNames() # 在程序启动时读取姓名列表
cap = cv2.VideoCapture(0)
while True:
# ... (人脸识别代码) ...
for encodeFace, faceLoc in zip(encodesCurFrame, facesCurFrame):
matches = face_recognition.compare_faces(encodeListKnown, encodeFace)
faceDis = face_recognition.face_distance(encodeListKnown, encodeFace)
matchIndex = np.argmin(faceDis)
if matches[matchIndex]:
name = classNames[matchIndex].upper()
# ... (绘制矩形框和文字) ...
markAttendance(name, nameList) # 传递 nameList代码解释:
注意事项
总结
通过在写入 CSV 文件之前进行姓名检查,可以有效地避免重复写入考勤记录。通过在程序启动时读取姓名列表,并将其存储在内存中,可以提高程序的效率。根据实际情况选择合适的优化方案,可以构建一个稳定、高效的人脸识别考勤系统。
以上就是解决人脸识别考勤系统重复写入CSV文件的问题的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号