You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于OpenCV的人脸考勤系统计数规则实现问询:签到计数递增与新人员计数重置

解决人脸考勤系统的签到计数递增问题

看起来你的代码目前存在的核心问题是固定使用count=1,不管是新用户还是老用户,每次签到的计数都是1,完全没实现按用户单独递增的逻辑。下面我会一步步帮你调整代码,实现需求中的计数规则:

核心思路

要实现每个用户的签到计数独立递增,我们需要:

  • 每次识别到已登录用户时,先读取当天的考勤记录文件,找到该用户之前的最大签到计数
  • 如果是该用户当天首次签到(或当天无考勤文件),计数从1开始;否则在之前的最大计数基础上加1
  • 把这个动态计算的count值写入考勤记录,而不是用固定的1

修改后的完整代码(关键部分已标注)

def TrackImages():
    check_haarcascadefile()
    assure_path_exists("Attendance/")
    assure_path_exists("StudentDetails/")
    for k in tv.get_children():
        tv.delete(k)
    msg = ''
    i = 0
    j = 0
    recognizer = cv2.face.LBPHFaceRecognizer_create()
    exists3 = os.path.isfile("TrainingImageLabel\Trainner.yml")
    if exists3:
        recognizer.read("TrainingImageLabel\Trainner.yml")
    else:
        mess._show(title='Data Missing', message='Please click on Save Profile to reset data!!')
        return
    harcascadePath = "haarcascade_frontalface_default.xml"
    faceCascade = cv2.CascadeClassifier(harcascadePath);
    cam = cv2.VideoCapture(0)
    font = cv2.FONT_HERSHEY_SIMPLEX
    col_names = ['Id', '', 'Name', '', 'Date', '', 'Count', '', 'In Time', '', 'Out Time']
    exists1 = os.path.isfile("StudentDetails\StudentDetails.csv")
    if exists1:
        df = pd.read_csv("StudentDetails\StudentDetails.csv")
    else:
        mess._show(title='Details Missing', message='Students details are missing, please check!')
        cam.release()
        cv2.destroyAllWindows()
        window.destroy()
    
    # 提前获取当天的考勤文件名,后续多次用到
    ts = time.time()
    date = datetime.datetime.fromtimestamp(ts).strftime('%d-%m-%Y')
    attendance_file_path = f"Attendance\AttendanceIn_{date}.csv"

    while True:
        ret, im = cam.read()
        gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
        faces = faceCascade.detectMultiScale(gray, 1.2, 5)
        for (x, y, w, h) in faces:
            cv2.rectangle(im, (x, y), (x + w, y + h), (225, 0, 0), 2)
            serial, conf = recognizer.predict(gray[y:y + h, x:x + w])
            if (conf < 50):
                ts = time.time()
                date = datetime.datetime.fromtimestamp(ts).strftime('%d-%m-%Y')
                timeStamp = datetime.datetime.fromtimestamp(ts).strftime('%H:%M:%S')
                aa = df.loc[df['SERIAL NO.'] == serial]['NAME'].values
                ID = df.loc[df['SERIAL NO.'] == serial]['ID'].values
                ID = str(ID)
                ID = ID[1:-1]
                bb = str(aa)
                bb = bb[2:-2]

                # ------------------- 关键修改:动态计算count值 -------------------
                count = 1  # 默认初始值为1(新用户或当天无记录)
                if os.path.isfile(attendance_file_path):
                    # 读取当天考勤文件,查询该用户的所有count记录
                    df_attendance = pd.read_csv(attendance_file_path)
                    # 筛选当前用户的记录,注意要处理空值和数据类型
                    user_records = df_attendance[df_attendance['Id'] == ID]
                    if not user_records.empty:
                        # 获取该用户最大的count值,加1作为本次的count
                        max_count = user_records['Count'].max()
                        count = max_count + 1
                # -----------------------------------------------------------

                attendance = [str(ID), '', bb, '', str(date), '', count, '', str(timeStamp), '', '']
            else:
                Id = 'Unknown'
                bb = str(Id)
            cv2.putText(im, str(bb), (x, y + h), font, 1, (255, 255, 255), 2)
        cv2.imshow('Taking Attendance', im)
        if (cv2.waitKey(1) == ord('q')):
            break
    psw()
    
    # 写入考勤记录部分保持不变,但用提前定义的文件路径
    exists = os.path.isfile(attendance_file_path)
    if exists:
        with open(attendance_file_path, 'a+') as csvFile1:
            writer = csv.writer(csvFile1)
            writer.writerow(attendance)
        csvFile1.close()
    else:
        with open(attendance_file_path, 'a+') as csvFile1:
            writer = csv.writer(csvFile1)
            writer.writerow(col_names)
            writer.writerow(attendance)
        csvFile1.close()
    with open(attendance_file_path, 'r') as csvFile1:
        reader1 = csv.reader(csvFile1)
        for lines in reader1:
            i = i + 1
            if (i > 1):
                if (i % 2 != 0):
                    iidd = str(lines[0]) + ' '
                    tv.insert('', 0, text=iidd, values=(str(lines[2]), str(lines[4]), str(lines[6])))
    csvFile1.close()
    cam.release()
    cv2.destroyAllWindows()

关键修改点说明

  1. 提前定义考勤文件路径:把当天的考勤文件路径提前计算好,避免重复代码,也方便后续读取和写入时统一使用。
  2. 动态计算count值:
    • 当识别到有效用户时,先检查当天的考勤文件是否存在
    • 如果存在,用Pandas读取文件,筛选出当前用户的所有记录
    • 如果该用户已有记录,取最大的count值加1;如果没有记录(或文件不存在),则count保持为1
  3. 保持原有写入逻辑:写入考勤记录的部分不需要大改,只需要替换成动态计算的count值即可

这样调整后,每个用户的签到计数就会独立递增了:新用户第一次签到count=1,第二次签到count=2,以此类推;老用户每次签到都会在之前的基础上加1,完全符合你的需求。

内容的提问来源于stack exchange,提问作者SAsUkE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 19:27:45