最近看机器学习,神经网络,图像识别是这个领域很常见的一种应用。使用著名的dlib库和微软RENET 68点模型做人脸识别,准确率高。
这程序演示了基本功能。
运行需要 shape_predictor_68_face_landmarks.dat, dlib_face_recognition_resnet_model_v1.dat,这两个数据文件,可在网上下载,
把需要识别的人脸照片 放在一个目录就可以了。
代码如下,转载请注明原文链接
# -*- coding: UTF-8 -*-
# weixin: yyckwen
# 2017/08/31 import sys,os,dlib,glob,numpy from skimage import io import pickle import time import cv2 import win32com.client import threading import queue import random from queue import Queue class langduface(threading.Thread): def __init__(self,f_name,speaker,pool): threading.Thread.__init__(self,name=f_name) self.data = pool self.speaker = speaker def run(self): yy = 1 while 1: try: n = self.data.get(1,10) print('pool:',self.data.qsize(),yy) if yy%10 == 1: self.speaker.Speak("欢迎, " + n) yy = yy + 1 except Exception as e: print(e) class jcface(threading.Thread): def __init__(self,f_name,pool,predictor_path,face_rec_model_path,faces_folder_path): threading.Thread.__init__(self,name=f_name) self.data = pool self.predictor_path = predictor_path self.face_rec_model_path = face_rec_model_path self.faces_folder_path = faces_folder_path self.face_names = [] self.reload = 0 self.descriptors = [] self.detector = dlib.get_frontal_face_detector() self.sp = dlib.shape_predictor(self.predictor_path) self.facerec = dlib.face_recognition_model_v1(self.face_rec_model_path) self.make_d() def set_reload(self): self.reload = 1 def get_model(self): return self.face_rec_model_path def make_d(self): if self.reload == 0: for f in glob.glob(os.path.join(self.faces_folder_path, "*.jpg")): print(("Processing file: {}".format(f))) # win = dlib.image_window() img = io.imread(f) dets = self.detector(img, 1) print("Number of faces detected:",len(dets)) for k, d in enumerate(dets): shape = self.sp(img, d) face_descriptor = self.facerec.compute_face_descriptor(img, shape) v = numpy.array(face_descriptor) d_v = (v, (f.split("\\")[-1]).split(".")[0]) self.descriptors.append(d_v) file = open('descriptors.pickle', 'wb') pickle.dump(self.descriptors, file) file.close() if self.reload == 1: with open('descriptors.pickle', 'rb') as file: self.descriptors = pickle.load(file) def d_face(self,ismall_frame): small_frame = ismall_frame dets = self.detector(small_frame, 1) dist = [] for k, d in enumerate(dets): shape = self.sp(small_frame, d) face_descriptor = self.facerec.compute_face_descriptor(small_frame, shape) d_test = numpy.array(face_descriptor) for i in self.descriptors: dist_ = numpy.linalg.norm(i[0] - d_test) dist_n = (dist_, i[1]) dist.append(dist_n) face_name = 'unknown' cd_sorted = sorted(dist, key=lambda d: d[0]) dist = [] if cd_sorted[0][0] < 0.6: face_name = cd_sorted[0][1] print("\n 这个人是: ", face_name) loc = (face_name, d, cd_sorted[0][0]) self.data.put(face_name) self.face_names.append(loc) print('\n 所有脸列表:', self.face_names, len(self.face_names)) def v_face(self): process_this_frame = True video_capture = cv2.VideoCapture(0) width = int(video_capture.get(cv2.CAP_PROP_FRAME_WIDTH) + 0.5) height = int(video_capture.get(cv2.CAP_PROP_FRAME_HEIGHT) + 0.5) while True: ret, frame = video_capture.read() small_frame = cv2.resize(frame, (0, 0), fx=0.5, fy=0.5) if process_this_frame: self.face_names = [] self.d_face(small_frame) process_this_frame = not process_this_frame for name, k, j in self.face_names: top = k.top() * 2 right = k.right() * 2 bottom = k.bottom() * 2 left = k.left() * 2 cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2) cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED) font = cv2.FONT_HERSHEY_DUPLEX cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1) cv2.imshow('Video', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break video_capture.release() cv2.destroyAllWindows() def run(self): self.v_face() def main(): print(sys.argv) #python facerer_rnet.py shape_predictor_68_face_landmarks.dat dlib_face_recognition_resnet_model_v1.dat ./faces/ if len(sys.argv) != 4: print("请检查参数是否正确。") exit() predictor_path = sys.argv[1] face_rec_model_path = sys.argv[2] faces_folder_path = sys.argv[3] pool = Queue() speaker = win32com.client.Dispatch("SAPI.SpVoice") t_jcface = jcface('jcface',pool,predictor_path, face_rec_model_path,faces_folder_path) t_speaker = langduface('facer',speaker,pool) t_jcface.start() t_speaker.start() t_jcface.join() t_speaker.join() if __name__ =='__main__': main()