我尝试使用 python opencv 功能获取实时考勤数据,但由于准确检测未知面孔的问题而无法实现,我尝试了不同的方法,但根本不起作用。每次我显示任何未存储在中的面孔时即使面孔未知,它仍然尝试显示数据库中已存在姓名的人的姓名
import cv2
import os
from flask import Flask, request, render_template, send_file
from datetime import date, datetime
import numpy as np
from sklearn.neighbors import KNeighborsClassifier
import pandas as pd
import joblib
# Defining Flask App
app = Flask(__name__)
nimgs = 10
# Saving Date today in 2 different formats
datetoday = date.today().strftime("%m_%d_%y")
datetoday2 = date.today().strftime("%d-%B-%Y")
# Initializing VideoCapture object to access WebCam
face_detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# If these directories don't exist, create them
if not os.path.isdir('Attendance'):
os.makedirs('Attendance')
if not os.path.isdir('static'):
os.makedirs('static')
if not os.path.isdir('static/faces'):
os.makedirs('static/faces')
if f'Attendance-{datetoday}.csv' not in os.listdir('Attendance'):
with open(f'Attendance/Attendance-{datetoday}.csv', 'w') as f:
f.write('Name,Roll,Time')
# get a number of total registered users
def totalreg():
return len(os.listdir('static/faces'))
# extract the face from an image
def extract_faces(img):
try:
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
face_points = face_detector.detectMultiScale(gray, 1.2, 5, minSize=(20, 20))
return face_points
except:
return []
# Identify face using ML model
def identify_face(facearray):
model = joblib.load('static/face_recognition_model.pkl')
return model.predict(facearray)
# A function which trains the model on all the faces available in faces folder
def train_model():
faces = []
labels = []
userlist = os.listdir('static/faces')
for user in userlist:
for imgname in os.listdir(f'static/faces/{user}'):
img = cv2.imread(f'static/faces/{user}/{imgname}')
resized_face = cv2.resize(img, (50, 50))
faces.append(resized_face.ravel())
labels.append(user)
faces = np.array(faces)
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(faces, labels)
joblib.dump(knn, 'static/face_recognition_model.pkl')
# Extract info from today's attendance file in attendance folder
def extract_attendance():
df = pd.read_csv(f'Attendance/Attendance-{datetoday}.csv')
names = df['Name']
rolls = df['Roll']
times = df['Time']
l = len(df)
return names, rolls, times, l
# Add Attendance of a specific user
def add_attendance(name):
username = name.split('_')[0]
userid = name.split('_')[1]
current_time = datetime.now().strftime("%H:%M:%S")
df = pd.read_csv(f'Attendance/Attendance-{datetoday}.csv')
if int(userid) not in list(df['Roll']):
with open(f'Attendance/Attendance-{datetoday}.csv', 'a') as f:
f.write(f'\n{username},{userid},{current_time}')
## A function to get names and rol numbers of all users
def getallusers():
userlist = os.listdir('static/faces')
names = []
rolls = []
l = len(userlist)
for i in userlist:
name, roll = i.split('_')
names.append(name)
rolls.append(roll)
return userlist, names, rolls, l
## A function to delete a user folder
def deletefolder(duser):
pics = os.listdir(duser)
for i in pics:
os.remove(duser+'/'+i)
os.rmdir(duser)
################## ROUTING FUNCTIONS #########################
# Our main page
@app.route('/')
def home():
names, rolls, times, l = extract_attendance()
return render_template('home.html', names=names, rolls=rolls, times=times, l=l, totalreg=totalreg(), datetoday2=datetoday2)
## List users page
@app.route('/listusers')
def listusers():
userlist, names, rolls, l = getallusers()
return render_template('listusers.html', userlist=userlist, names=names, rolls=rolls, l=l, totalreg=totalreg(), datetoday2=datetoday2)
## Delete functionality
@app.route('/deleteuser', methods=['GET'])
def deleteuser():
duser = request.args.get('user')
deletefolder('static/faces/'+duser)
## if all the face are deleted, delete the trained file...
if os.listdir('static/faces/')==[]:
os.remove('static/face_recognition_model.pkl')
try:
train_model()
except:
pass
userlist, names, rolls, l = getallusers()
return render_template('listusers.html', userlist=userlist, names=names, rolls=rolls, l=l, totalreg=totalreg(), datetoday2=datetoday2)
# Our main Face Recognition functionality.
# This function will run when we click on Take Attendance Button.
@app.route('/start', methods=['GET'])
def start():
# Clear previous attendance data
with open(f'Attendance/Attendance-{datetoday}.csv', 'w') as f:
f.write('Name,Roll,Time')
# Extract attendance data for display
names, rolls, times, l = extract_attendance()
if 'face_recognition_model.pkl' not in os.listdir('static'):
return render_template('home.html', names=names, rolls=rolls, times=times, l=l, totalreg=totalreg(), datetoday2=datetoday2, mess='There is no trained model in the static folder. Please add a new face to continue.')
ret = True
cap = cv2.VideoCapture(0)
while ret:
ret, frame = cap.read()
if len(extract_faces(frame)) > 0:
(x, y, w, h) = extract_faces(frame)[0]
cv2.rectangle(frame, (x, y), (x+w, y+h), (86, 32, 251), 1)
cv2.rectangle(frame, (x, y), (x+w, y-40), (86, 32, 251), -1)
face = cv2.resize(frame[y:y+h, x:x+w], (50, 50))
identified_person = identify_face(face.reshape(1, -1))[0]
add_attendance(identified_person)
cv2.putText(frame, f'{identified_person}', (x+5, y-5),
cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
cv2.imshow('Attendance', frame)
key = cv2.waitKey(1) # Capture the pressed key
if key == ord('q') or key == 27: # If 'q' or 'Esc' is pressed, break the loop
break
cap.release()
cv2.destroyAllWindows()
# Extract new attendance data for display after updating
names, rolls, times, l = extract_attendance()
return render_template('home.html', names=names, rolls=rolls, times=times, l=l, totalreg=totalreg(), datetoday2=datetoday2)
# A function to add a new user.
# This function will run when we add a new user.
@app.route('/add', methods=['GET', 'POST'])
def add():
newusername = request.form['newusername']
newuserid = request.form['newuserid']
userimagefolder = 'static/faces/'+newusername+'_'+str(newuserid)
if not os.path.isdir(userimagefolder):
os.makedirs(userimagefolder)
i, j = 0, 0
cap = cv2.VideoCapture(0)
while 1:
_, frame = cap.read()
faces = extract_faces(frame)
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 20), 2)
cv2.putText(frame, f'Images Captured: {i}/{nimgs}', (30, 30),
cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 20), 2, cv2.LINE_AA)
if j % 5 == 0:
name = newusername+'_'+str(i)+'.jpg'
cv2.imwrite(userimagefolder+'/'+name, frame[y:y+h, x:x+w])
i += 1
j += 1
if j == nimgs*5:
break
cv2.imshow('Adding new User', frame)
if cv2.waitKey(1) == 27:
break
cap.release()
cv2.destroyAllWindows()
print('Training Model')
train_model()
names, rolls, times, l = extract_attendance()
return render_template('home.html', names=names, rolls=rolls, times=times, l=l, totalreg=totalreg(), datetoday2=datetoday2)
# Route for downloading attendance
@app.route('/download', methods=['POST'])
def download_attendance():
# Extract attendance data
names, rolls, times, l = extract_attendance()
# Create DataFrame for attendance data
df = pd.DataFrame({'Name': names, 'Employee_ID': rolls, 'Time': times})
# Save DataFrame to Excel file
excel_file_path = f'Attendance/Attendance-{datetoday}.xlsx'
df.to_excel(excel_file_path, index=False)
# Return Excel file for download
return send_file(excel_file_path, as_attachment=True)
# Our main function which runs the Flask App
if __name__ == '__main__':
app.run(debug=True)
您正在检查模型是否检测到任何人脸:
if len(extract_faces(frame)) > 0:
...
但这并不能保证该人脸在数据库中。请注意,检测(任何面部)和识别(特定面部)之间存在差异。 此处识别、显示并记录人脸:
identified_person = identify_face(face.reshape(1, -1))[0] # Might not have indentified who the face is
add_attendance(identified_person)
cv2.putText(frame, f'{identified_person}', (x+5, y-5),
cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
如果该面不存在,
identified_person
将是None
或标识符返回的任何内容。如果未识别出该人脸,您可以 continue
移至下一个 检测到的 人脸。