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

DDD
发布: 2025-10-21 12:03:05
原创
1013人浏览过

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

本文针对基于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}')
登录后复制

代码解释:

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

优化建议

AI建筑知识问答
AI建筑知识问答

用人工智能ChatGPT帮你解答所有建筑问题

AI建筑知识问答 22
查看详情 AI建筑知识问答

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

  1. 在程序启动时读取姓名列表: 在程序启动时,一次性读取 CSV 文件中的所有姓名,并将其存储在内存中。
  2. 更新内存中的姓名列表: 每次成功写入新的考勤记录后,立即将该姓名添加到内存中的姓名列表中。
  3. 使用 "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 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
登录后复制

代码解释:

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

注意事项

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

总结

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

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

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号