基于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()
关键修改点说明
- 提前定义考勤文件路径:把当天的考勤文件路径提前计算好,避免重复代码,也方便后续读取和写入时统一使用。
- 动态计算count值:
- 当识别到有效用户时,先检查当天的考勤文件是否存在
- 如果存在,用Pandas读取文件,筛选出当前用户的所有记录
- 如果该用户已有记录,取最大的count值加1;如果没有记录(或文件不存在),则count保持为1
- 保持原有写入逻辑:写入考勤记录的部分不需要大改,只需要替换成动态计算的count值即可
这样调整后,每个用户的签到计数就会独立递增了:新用户第一次签到count=1,第二次签到count=2,以此类推;老用户每次签到都会在之前的基础上加1,完全符合你的需求。
内容的提问来源于stack exchange,提问作者SAsUkE
相关产品推荐
相关产品推荐

