python多进程,使用用微软RENET模型的视频人脸识别程序

最近看机器学习,神经网络,图像识别是这个领域很常见的一种应用。使用著名的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()

你可能感兴趣的:(机器学习,人脸识别)