赞
踩
基于人脸识别的课堂考勤系统
课堂考勤是保证学生出勤率的重要手段之一,也是学生课程成绩重要的组成部分,课堂考勤可以很好的监督学生,从而确保了课堂的教学质量。目前主要的考勤手段仍然是教师人工点名或者随机抽查的方式,这种人工点名的方式不仅占用上课时间而且无法解决学生的早退、代签和旷课等现象,无法很好的对学生考勤做到监管.市面上也存在着各种各样的考勤机,但是由于硬件和部署的成本较高,无法很好的解决考勤问题。
为了解决上述的问题,本文采用人脸识别技术,设计实现了一个适合日常课堂考勤的自动化人脸识别考勤系统,主要研究了该系统的设计与功能的实现。阐述了人脸识别技术的基本概念、发展阶段和基本方法,分析了传统考勤方式的不足,同时也介绍了国内外相关技术的发展历史和研究成果。接着详细介绍了活体检测、人脸检测及人脸识别的主要方法。然后根据考勤系统在功能和性能上的各种需求,进行软件架构的设计。最终整体介绍系统的功能以及测试内容,并展示了相应的GUI界面。
利用python实现人脸识别技术是基于mtcnn和facenet考勤
实现了人脸大角度识别
- import cv2
- import os
- import numpy as np
- from net.mtcnn import mtcnn
- import utils.utils as utils
- from net.inception import InceptionResNetV1
- import time
- from dateutil.parser import parse
-
-
- font = cv2.FONT_HERSHEY_COMPLEX
-
- def seekopp(list_2,i):
- for j in range(i-1,-1,-1):
- if list_2[j]==0:
- continue
- elif list_2[j]>0:
- return 1
- elif list_2[j]<0:
- return 0
-
- def local_maximum(list_1):
- a=len(list_1)
- if a==0:
- return 'error'
- if a==1:
- return list_1
- if a==2:
- if list_1[0]>list_1[1]:
- return list_1[0]
- elif list_1[0]<list_1[1]:
- return list_1[1]
- else:
- return list_1
- if a>2:
- list_2=[]
- index_1=[]
- for i in range(0,a-1):
- list_2.append(list_1[i+1]-list_1[i])
- b=len(list_2)
- if list_2[0]<0:
- index_1.append(0)
- for i in range(0,b-1):
- if list_2[i+1]<0:
- if list_2[i]>0:
- index_1.append(i+1)
- elif list_2[i]==0:
- if seekopp(list_2,i):
- index_1.append(i+1)
- else:
- continue
- else:
- continue
- list_3=[]
- for i in index_1:
- list_3.append(list_1[i])
- return list_3
-
- def transform(t1,t2):
- timeArray1 = time.localtime(t1)
- timeArray2 = time.localtime(t2)
- time_1 = time.strftime("%Y-%m-%d %H:%M:%S", timeArray1)
- time_2 = time.strftime("%Y-%m-%d %H:%M:%S", timeArray2)
- date1 = parse(time_1)
- date2 = parse(time_2)
- result = int((date2 - date1).total_seconds())
- return result
-
-
- class face_rec():
- time = 0
- def __init__(self):
- # 创建mtcnn对象
- # 检测图片中的人脸
- self.mtcnn_model = mtcnn()
- # 门限函数
- self.threshold = [0.5,0.8,0.9]
- # 载入facenet
- # 将检测到的人脸转化为128维的向量
- self.facenet_model = InceptionResNetV1()
- # model.summary()
- model_path = './model_data/facenet_keras.h5'
- self.facenet_model.load_weights(model_path)
-
- #-----------------------------------------------#
- # 对数据库中的人脸进行编码
- # known_face_encodings中存储的是编码后的人脸
- # known_face_names为人脸的名字
- #-----------------------------------------------#
- face_list = os.listdir("face_dataset")
- self.known_face_encodings=[]
- self.known_face_names=[]
- self.time_list=[]
- self_learn_time = 0
- self.total_time = []
-
- for face in face_list:
- name = face.split(".")[0]
-
- img = cv2.imread("./face_dataset/"+face)
- img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
-
- # 检测人脸
- rectangles = self.mtcnn_model.detectFace(img, self.threshold)
-
- # 转化成正方形
- rectangles = utils.rect2square(np.array(rectangles))
- # facenet要传入一个160x160的图片
- rectangle = rectangles[0]
- # 记下他们的landmark
- landmark = (np.reshape(rectangle[5:15],(5,2)) - np.array([int(rectangle[0]),int(rectangle[1])]))/(rectangle[3]-rectangle[1])*160
-
- crop_img = img[int(rectangle[1]):int(rectangle[3]), int(rectangle[0]):int(rectangle[2])]
- crop_img = cv2.resize(crop_img,(160,160))
-
- new_img,_ = utils.Alignment_1(crop_img,landmark)
-
- new_img = np.expand_dims(new_img,0)
- # 将检测到的人脸传入到facenet的模型中,实现128维特征向量的提取
- face_encoding = utils.calc_128_vec(self.facenet_model,new_img)
-
- self.known_face_encodings.append(face_encoding)
- self.known_face_names.append(name)
-
- def recognize(self,draw):
- #-----------------------------------------------#
- # 人脸识别
- # 先定位,再进行数据库匹配
- #-----------------------------------------------#
- height,width,_ = np.shape(draw)
- draw_rgb = cv2.cvtColor(draw,cv2.COLOR_BGR2RGB)
- # 检测人脸
- rectangles = self.mtcnn_model.detectFace(draw_rgb, self.threshold)
- '''
- if len(rectangles)==0:
- font = cv2.FONT_HERSHEY_SIMPLEX
- if time_flag==0:
- print('首次执行!')
- first_time = time.time()
- t = transform(int(first_time),int(time.time()))
- cv2.putText(draw, "Focus on time:"+str(t)+" s", (250, 40), font, 0.6, (0, 255, 0), 1, cv2.LINE_AA)
- time_flag==1
- return
- else:
- print('第二次执行!')
- t = transform(int(first_time),int(time.time()))
- cv2.putText(draw, "Focus on time:"+str(t)+" s", (250, 40), font, 0.6, (0, 255, 0), 1, cv2.LINE_AA)
- return
- '''
- if len(rectangles)==0:
- self.time_list.append(time.time())
- font = cv2.FONT_HERSHEY_SIMPLEX
- t = transform(self.time_list[0],self.time_list[-1])
- #print(t,type(t))
- cv2.putText(draw, "Noface", (40, 40), font, 0.6, (0, 255, 0), 1, cv2.LINE_AA)
- cv2.putText(draw, "Focus on time:"+str(t)+" s", (350, 40), font, 0.6, (0, 255, 0), 1, cv2.LINE_AA)
- #print(self.total_time,type(self.total_time))
- if len(self.total_time)==0:
- self.total_time.append(t)
- elif self.total_time[-1]<= t:
- self.total_time.pop()
- self.total_time.append(t)
- elif self.total_time[-1]>= t:
- self.total_time.append(t)
- else:
- pass
- return draw,self.total_time
- self.time_list.clear()
- # 转化成正方形
- rectangles = utils.rect2square(np.array(rectangles,dtype=np.int32))
- rectangles[:,0] = np.clip(rectangles[:,0],0,width)
- rectangles[:,1] = np.clip(rectangles[:,1],0,height)
- rectangles[:,2] = np.clip(rectangles[:,2],0,width)
- rectangles[:,3] = np.clip(rectangles[:,3],0,height)
- #-----------------------------------------------#
- # 对检测到的人脸进行编码
- #-----------------------------------------------#
- face_encodings = []
- for rectangle in rectangles:
- landmark = (np.reshape(rectangle[5:15],(5,2)) - np.array([int(rectangle[0]),int(rectangle[1])]))/(rectangle[3]-rectangle[1])*160
-
- crop_img = draw_rgb[int(rectangle[1]):int(rectangle[3]), int(rectangle[0]):int(rectangle[2])]
- crop_img = cv2.resize(crop_img,(160,160))
-
- new_img,_ = utils.Alignment_1(crop_img,landmark)
- new_img = np.expand_dims(new_img,0)
-
- face_encoding = utils.calc_128_vec(self.facenet_model,new_img)
- face_encodings.append(face_encoding)
-
- face_names = []
- for face_encoding in face_encodings:
- # 取出一张脸并与数据库中所有的人脸进行对比,计算得分
- matches = utils.compare_faces(self.known_face_encodings, face_encoding, tolerance = 0.9)
- name = "Unknown"
- # 找出距离最近的人脸
- face_distances = utils.face_distance(self.known_face_encodings, face_encoding)
- # 取出这个最近人脸的评分
- best_match_index = np.argmin(face_distances)
- if matches[best_match_index]:
- name = self.known_face_names[best_match_index]
- face_names.append(name)
-
- rectangles = rectangles[:,0:4]
- #-----------------------------------------------#
- # 画框~!~
- #-----------------------------------------------#
- for (left, top, right, bottom), name in zip(rectangles, face_names):
- cv2.rectangle(draw, (left, top), (right, bottom), (0, 0, 255), 2)
-
- font = cv2.FONT_HERSHEY_SIMPLEX
- cv2.putText(draw, name, (left , bottom - 15), font, 0.75, (255, 255, 255), 2)
-
- if name!='Unknown':
- cv2.putText(draw, 'name:'+name, (10, 20), font, 0.6, (0, 255, 0), 1, cv2.LINE_AA)
- cv2.putText(draw, "state:"+"clock on", (10, 60), font, 0.6, (0, 255, 0), 1, cv2.LINE_AA)
- cv2.putText(draw, "Please concentrate on your study!", (200, 40), font, 0.6, (0, 0, 255), 1, cv2.LINE_AA)
- else:
- cv2.putText(draw, 'name:'+name, (10, 20), font, 0.6, (0, 255, 0), 1, cv2.LINE_AA)
- cv2.putText(draw, "state:"+"clock out failed", (10, 60), font, 0.6, (0, 255, 0), 1, cv2.LINE_AA)
- cv2.putText(draw, "Please add face!", (300, 40), font, 0.6, (0, 0, 255), 1, cv2.LINE_AA)
-
- return draw,self.total_time
-
- if __name__ == "__main__":
-
- dududu = face_rec()
- video_capture = cv2.VideoCapture(0)
-
- while True:
- ret, draw = video_capture.read()
- dududu.recognize(draw)
- cv2.imshow('Video', draw)
- if cv2.waitKey(20) & 0xFF == ord('q'):
- break
-
- video_capture.release()
- cv2.destroyAllWindows()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。