解决人脸识别考勤系统重复写入CSV文件的问题

解决人脸识别考勤系统重复写入csv文件的问题

本文针对基于OpenCV和face_recognition库构建的人脸识别考勤系统,解决了在摄像头持续识别人脸时,重复将考勤记录写入CSV文件的问题。通过调整代码逻辑,确保每个人只记录一次考勤信息,并提供优化建议,提高程序效率。

在构建人脸识别考勤系统时,一个常见的挑战是避免重复记录考勤信息。以下将详细介绍如何修改代码,确保每个人只记录一次考勤,并提供一些优化建议。

问题分析

原始代码在主循环中,每次检测到人脸匹配时,都会调用 markAttendance 函数。由于摄像头帧率很高,即使人脸只出现一次,也会被多次检测到,导致重复写入 CSV 文件。

解决方案

核心思路是:在将姓名写入文件之前,先检查该姓名是否已经存在于已记录的姓名列表中。如果存在,则跳过写入操作;否则,才进行写入。以下是修改后的 markAttendance 函数:

from datetime import datetimedef 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}')

代码解释:

读取现有数据: f.readlines() 读取整个文件的所有行,并将其存储在 myDataList 列表中。提取已记录的姓名: 循环遍历 myDataList,将每一行按照逗号分隔,提取出姓名,并将其添加到 nameList 列表中。检查姓名是否已存在: 使用 if name not in nameList: 判断当前检测到的姓名是否已经存在于 nameList 中。写入考勤记录: 如果姓名不存在,则获取当前时间,格式化为字符串,并将姓名和时间写入 CSV 文件。

优化建议

虽然上述代码可以解决重复写入的问题,但每次调用 markAttendance 函数时都读取整个 CSV 文件效率较低。可以进行以下优化:

在程序启动时读取姓名列表: 在程序启动时,一次性读取 CSV 文件中的所有姓名,并将其存储在内存中。更新内存中的姓名列表: 每次成功写入新的考勤记录后,立即将该姓名添加到内存中的姓名列表中。使用 “a” 模式打开文件: 在markAttendance函数中使用追加模式 “a” 打开文件,而不是 “r+” 模式,简化写入操作。

以下是优化后的代码示例:

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 nameListdef 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

代码解释:

readNames() 函数: 在程序启动时调用,读取 CSV 文件中的所有姓名,并将其存储在 nameList 列表中。增加了异常处理,如果文件不存在则创建。markAttendance() 函数: 接收 nameList 作为参数,直接在内存中进行姓名检查,并将新的姓名添加到 nameList 中。使用 “a” 模式打开文件,进行追加写入。主程序: 在主循环中,将 nameList 传递给 markAttendance() 函数。

注意事项

确保 CSV 文件存在,并且具有正确的格式(姓名,时间)。如果文件不存在,readNames() 函数会创建一个空文件。根据实际情况调整人脸识别的灵敏度,避免误识别导致错误的考勤记录。可以考虑使用数据库存储考勤数据,以便进行更复杂的查询和分析。

总结

通过在写入 CSV 文件之前进行姓名检查,可以有效地避免重复写入考勤记录。通过在程序启动时读取姓名列表,并将其存储在内存中,可以提高程序的效率。根据实际情况选择合适的优化方案,可以构建一个稳定、高效的人脸识别考勤系统。

以上就是解决人脸识别考勤系统重复写入CSV文件的问题的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1378009.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月14日 18:16:18
下一篇 2025年12月14日 18:16:37

相关推荐

发表回复

登录后才能评论
关注微信