logo资料库

用树莓派实现人脸识别打卡门禁系统.pdf

第1页 / 共6页
第2页 / 共6页
第3页 / 共6页
第4页 / 共6页
第5页 / 共6页
第6页 / 共6页
资料共6页,全文预览结束
用树莓派实现人脸识别打卡门禁系统 用树莓派实现人脸识别打卡门禁系统 用树莓派实现人脸识别打卡门禁系统的构建 用树莓派实现人脸识别打卡门禁系统的构建背景功能硬件效果源码摄像头测试代码录入信息人脸识别结论 背景背景 源于实习公司的人脸识别打卡系统,完成之前的项目后正好没有事情干,于是想到了这个,公司的这个打卡系统操作流程是这 样的,首先用手机把你的人脸录进去,要求绕头半圈,也就是右脸,正脸,左脸,然后你再去摄像头那里,识别到你后就会帮 你把门打开,顺便帮你在钉钉上打卡。 功能功能 我做的是简易版,实现了这个打卡系统的主要功能,能完成:信息录入,正脸识别,开门关门,名字与时间的保存。 硬件硬件 树莓派一个,摄像头一个,显示屏一个 效果效果 并没有打马赛克,文件大小还被限制了,大家将就着看, 这是在电脑上的效果: 在树莓派上效果:
打卡记录: 看起来效果还是不错的 源码源码 源码使用的电脑上的源码,其实是差不多的,路径不一样而已 如果树莓派打不开摄像头,参考这个:
https://www.jianshu.com/p/5653b2b7248c 代码注释很全,不详细解释 摄像头测试代码 摄像头测试代码 import cv2 capCamera = cv2.VideoCapture(0) if(not capCamera.isOpened()): print("can't open this camera") exit(0) capCamera.set(cv2.CAP_PROP_FRAME_WIDTH, 320) capCamera.set(cv2.CAP_PROP_FRAME_HEIGHT, 240) while(True): # handle for the camera ret, frame = capCamera.read() if ret == True: cv2.imshow('camera',frame) else: break # handle for the video # handle for exit if (cv2.waitKey(1)) == ord('q'): break capCamera.release() cv2.destroyAllWindows() 录入信息 录入信息 import cv2 import os #config add_name = 'xiaoming'#要录入的人名 target_dir = './pic_dir/{}/'.format(add_name) if os.path.exists(target_dir) is False: os.makedirs(target_dir) def generate(): face_cascade = cv2.CascadeClassifier('.\cascades\haarcascade_frontalface_default.xml') #打开摄像头 camera = cv2.VideoCapture(0) forword_count = 0 #正脸采集,一共20张图片 while (forword_count <= 20): ret, frame = camera.read() #转化为灰度图像,用来检测人脸 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, 1.3, 5) for (x, y, w, h) in faces: #画出预测框 cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2) f = cv2.resize(gray[y:y + h, x:x + w], (200, 200)) #保存录入的图片 cv2.imwrite('./pic_dir/{0}/{1}.png'.format(add_name, forword_count), f) print(forword_count) forword_count += 1 #展示图片 cv2.imshow("camera", frame) #一秒钟24帧 if cv2.waitKey(1000 // 24) & 0xff == ord("q"): break camera.release()
cv2.destroyAllWindows() if __name__ == "__main__": generate() 人脸识别 人脸识别 import os import sys import cv2 import numpy as np import time def change_door(open_later_time,isOpen,new_face_position): if len(new_face_position) > 0 and isOpen == False: print('打开') isOpen = True if len(new_face_position) == 0 and isOpen == True: open_later_time += 1 else: open_later_time = 0 if open_later_time == 100: open_later_time = 0 print('关闭') isOpen = False return open_later_time,isOpen,new_face_position def read_images(path, sz=None):#给一个地址,返回训练集 c = 0 X, Y = [], [] names = [] for dirname, dirnames, filenames in os.walk(path):#目录,子目录,子文件(只限一层目录) for subdirname in dirnames: names.append(subdirname) subject_path = os.path.join(dirname, subdirname) for filename in os.listdir(subject_path):#遍历每个名字 try: if (filename == ".directory"): continue filepath = os.path.join(subject_path, filename) im = cv2.imread(filepath, cv2.IMREAD_GRAYSCALE) if (im is None): print("image " + filepath + " is none") else: print(filepath) if (sz is not None): im = cv2.resize(im, (200, 200)) X.append(np.asarray(im, dtype=np.uint8)) Y.append(c) except IOError: print("I/O error({0}): {1}".format(IOError.errno, IOError.strerror)) except: print("Unexpected error:", sys.exc_info()[0]) raise print(c) c = c + 1 print(Y) print(names) return [X, Y], names def face_rec(): image_dir = './pic_dir_1' isOpen = False open_later_time = 0 [X, Y] , names = read_images(image_dir) Y = np.asarray(Y, dtype=np.int32) model = cv2.face.LBPHFaceRecognizer_create()
model.train(np.asarray(X), np.asarray(Y)) camera = cv2.VideoCapture(0) camera.set(cv2.CAP_PROP_FRAME_WIDTH, 400) camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 350) face_cascade = cv2.CascadeClassifier('./cascades/haarcascade_frontalface_default.xml') re_count = 0 old_face_position = {}#用来绘制预测框 new_face_position = {}#用来收集新数据 while (True): #print(old_face_position) #print(new_face_position) re_count += 1 read, img = camera.read() faces = face_cascade.detectMultiScale(img, scaleFactor =1.3, minNeighbors=5) #print('{}的类型{}'.format(faces, type(faces))) for (x, y, w, h) in faces: gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) roi = gray[x:x + w, y:y + h] try: roi = cv2.resize(roi, (200, 200), interpolation=cv2.INTER_LINEAR) #print(roi.shape) params = model.predict(roi) #print("Label: %s, Confidence: %.2f" % (params[0], params[1])) new_face_position[names[params[0]]] = (x, y, w, h) except: continue #优化用户体验 #采集三帧的人脸识别信息,将预测框画出,预测框三帧一刷新,防止预测框频繁抖动的现象 if re_count == 3: re_count = 0 #print(new_face_position) if len(new_face_position) > 0: for key in new_face_position.keys(): (x, y, w, h) = new_face_position[key] if old_face_position.__contains__(key) is False: img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2) cv2.putText(img, key, (x, y - 20), cv2.FONT_HERSHEY_SIMPLEX, 1, 255, 2) old_face_position[key] = (x, y, w, h) else: (o_x, o_y, o_w, o_h) = new_face_position[key] if abs((o_x-x)) <= 5 and abs((o_y-y)) 0 and isOpen == False: print('开门') #保存打卡信息 t = time.strftime('%Y.%m.%d %H:%M:%S', time.localtime(time.time())) with open('jilu.txt', 'a') as file: file.writelines('{},{}\n'.format(new_face_position.keys(),t)) isOpen = True #如果没有检测到人,并且门开了,计数器+1,否则计数器为0 if len(new_face_position) == 0 and isOpen == True: open_later_time += 1 else: open_later_time = 0 #当计数器为100的时候关门 if open_later_time == 100: print('关门') isOpen = False open_later_time = 0 cv2.imshow("camera", img) #树莓派最好将帧数设为最大,不然看起来不舒服 if cv2.waitKey(1000 // 25) & 0xff == ord("q"): #if cv2.waitKey(1000 // 25) & 0xff == ord("q"): break cv2.destroyAllWindows() if __name__ == "__main__": face_rec() 结论结论 在电脑上运行的很流畅,在树莓派上运行的话因树莓派而异,能明显感觉到帧数下降,不过基本功能还是能完成的
作者:(DᴗD)B
分享到:
收藏