mtcnn结合face_recognition实现视频流中人脸实时识别

一、 本文结构

1、算法相关库的安装
2、视频中人脸识别的底库文件生成
3、视频流中人脸识别
mtcnn模型同样使用上一篇文章中已经训练好的模型

二、 算法环境搭建以及相关库安装

与上文相同,不在赘述

三、 视频中人脸识别的底库文件生成

实际上是与图片中人脸识别的底库生成思路是相同的,最后生成.pickle文件
class_video.py

# coding:utf-8
import os
import face_recognition
import pickle

# 加载mtcnn模块
# 加载mtcnn模块
from training.mtcnn_model import P_Net, R_Net, O_Net
from tools.loader import TestLoader
from detection.MtcnnDetector import MtcnnDetector
from detection.detector import Detector
from detection.fcn_detector import FcnDetector
from face_recognition.face_recognition_cli import image_files_in_folder


def net(stage):
    detectors = [None, None, None]
    if stage in ['pnet', 'rnet', 'onet']:
        modelPath = "/home/alex/face_recognize/mtcnn_fance-recognize/main/tmp/model/pnet"
        a = [b[5:-6] for b in os.listdir(modelPath) if b.startswith('pnet-') and b.endswith('.index')]
        maxEpoch = max(map(int, a))  # auto match a max epoch model
        modelPath = os.path.join(modelPath, "pnet-%d" % (maxEpoch))
        print("Use PNet model: %s" % (modelPath))
        detectors[0] = FcnDetector(P_Net, modelPath)
    if stage in ['rnet', 'onet']:
        modelPath = "/home/alex/face_recognize/mtcnn_fance-recognize/main/tmp/model/rnet"
        a = [b[5:-6] for b in os.listdir(modelPath) if b.startswith('rnet-') and b.endswith('.index')]
        maxEpoch = max(map(int, a))
        modelPath = os.path.join(modelPath, "rnet-%d" % (maxEpoch))
        print("Use RNet model: %s" % (modelPath))
        detectors[1] = Detector(R_Net, 24, 1, modelPath)
    if stage in ['onet']:
        modelPath = "/home/alex/face_recognize/mtcnn_fance-recognize/main/tmp/model/onet"
        a = [b[5:-6] for b in os.listdir(modelPath) if b.startswith('onet-') and b.endswith('.index')]
        maxEpoch = max(map(int, a))
        modelPath = os.path.join(modelPath, "onet-%d" % (maxEpoch))
        print("Use ONet model: %s" % (modelPath))
        detectors[2] = Detector(O_Net, 48, 1, modelPath)
        return detectors


def train(train_dir, save_model_path):
    knownname= []
    knownencodings = []
    for i in os.listdir(train_dir):
        class_path = os.path.join(train_dir, i)
        class_name = i
        for img in os.listdir(os.path.join(train_dir, i)):

            # print(img)
            full_img_path = os.path.join(class_path, img)
            pic_list = []
            face_location = []
            pic_list.append(full_img_path)
            textDatas = TestLoader(pic_list)
            allBoxes, _ = mtcnnDetector.detect_face(textDatas)
            for box in allBoxes[0]:
                x1 = int(box[0])
                y1 = int(box[1])
                x2 = int(box[2])
                y2 = int(box[3])
            face_location.append((y1 - 10, x2 + 12, y2 + 10, x1 - 12))
            if len(face_location) != 1:
                if len(face_location) <= 1:
                    print('no face in the pic')
                else:
                    print('no suitable face in the pic')
                return []

            image = face_recognition.load_image_file(full_img_path)
            face_encodings = face_recognition.face_encodings(face_image=image, known_face_locations=face_location, num_jitters=6)
            for encoding in face_encodings:
                knownname.append(class_name)
                knownencodings.append(encoding)
    data = {'encodings': knownencodings, 'names': knownname}
    with open(save_model_path, 'wb') as f:
        f.write(pickle.dumps(data))
        f.close()


if __name__ == "__main__":
    train_dir = "/home/alex/face_recognize/mtcnn_fance-recognize/datasets "
    save_madel_path = "/home/alex/face_recognize/mtcnn_fance-recognize/main 2/video_classifer_model_1.pickle"
    detectors = net("onet")
    os.environ["CUDA_VISIBLE_DEVICES"] = '0'
    mtcnnDetector = MtcnnDetector(detectors=detectors, min_face_size=40, threshold=[0.9, 0.6, 0.7])
    train(train_dir=train_dir, save_model_path=save_madel_path)

四、 MTCNN算法与face-recognition算法结合实现视频流中人脸识别

实际的操作就是使用opencv将视频流中的每一帧当做图片处理。
code思路与图片中的人脸检测相同,只是将视频流中的每一帧当做图片处理

# coding:utf-8
import os
import face_recognition
import cv2
import numpy as np
import pickle
# 加载mtcnn模块
from training.mtcnn_model import P_Net, R_Net, O_Net
from tools.loader import TestLoader
from detection.MtcnnDetector import MtcnnDetector
from detection.detector import Detector
from detection.fcn_detector import FcnDetector
from face_recognition.face_recognition_cli import image_files_in_folder


def net(stage):
    detectors = [None, None, None]
    if stage in ['pnet', 'rnet', 'onet']:
        modelPath = "/home/alex/face_recognize/mtcnn_fance-recognize/main/tmp/model/pnet"
        a = [b[5:-6] for b in os.listdir(modelPath) if b.startswith('pnet-') and b.endswith('.index')]
        maxEpoch = max(map(int, a))  # auto match a max epoch model
        modelPath = os.path.join(modelPath, "pnet-%d" % (maxEpoch))
        print("Use PNet model: %s" % (modelPath))
        detectors[0] = FcnDetector(P_Net, modelPath)
    if stage in ['rnet', 'onet']:
        modelPath = "/home/alex/face_recognize/mtcnn_fance-recognize/main/tmp/model/rnet"
        a = [b[5:-6] for b in os.listdir(modelPath) if b.startswith('rnet-') and b.endswith('.index')]
        maxEpoch = max(map(int, a))
        modelPath = os.path.join(modelPath, "rnet-%d" % (maxEpoch))
        print("Use RNet model: %s" % (modelPath))
        detectors[1] = Detector(R_Net, 24, 1, modelPath)
    if stage in ['onet']:
        modelPath = "/home/alex/face_recognize/mtcnn_fance-recognize/main/tmp/model/onet"
        a = [b[5:-6] for b in os.listdir(modelPath) if b.startswith('onet-') and b.endswith('.index')]
        maxEpoch = max(map(int, a))
        modelPath = os.path.join(modelPath, "onet-%d" % (maxEpoch))
        print("Use ONet model: %s" % (modelPath))
        detectors[2] = Detector(O_Net, 48, 1, modelPath)
        return detectors


def recognize(model_path):
    cap = cv2.VideoCapture(0)
    ret, frame = cap.read()
    while ret:
        face_location = []
        names = []
        _, frame = cap.read()
        image = np.array(frame)
        allBoxs, _ = mtcnnDetector.detect_video(image)
        # print(allBoxs)
        for box in allBoxs:
            x1 = int(box[0])
            y1 = int(box[1])
            x2 = int(box[2])
            y2 = int(box[3])
        face_location.append((y1 - 10, x2 + 12, y2 + 10, x1 - 12))

        face_encodings = face_recognition.face_encodings(frame, face_location, num_jitters=6)
        print(face_encodings)
        for face_encoding in face_encodings:
            matches = face_recognition.compare_faces(known_face_encodings=data['encodings'], face_encoding_to_check=face_encoding, tolerance=0.45)
            name = 'Unknown'
            if True in matches:
                matchesid = [i for (i, b) in enumerate(matches) if b]
                counts = {}
                for i in matchesid:
                    name = model_path['names'][i]
                    counts[name] = counts.git(name, 0) + 1
                name = max(counts, key=counts.get)
            names.append(name)
        for ((top, right, bottom, left), name) in zip(face_location, names):
            y1 = int(top)
            x1 = int(right)
            y2 = int(bottom)
            x2 = int(left)
            cv2.rectangle(frame, (x2,y1), (x1,y2), (0, 0, 255), 2)
            cv2.putText(frame, (x2, y1-5), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
        cv2.imshow("recognize", frame)

        if cv2.waitKeyEx(1) & 0xFF == ord('q'):
            break
    cv2.destroyAllWindows()
    cap.release()


if __name__ == "__main__":
    model_path = "/home/alex/face_recognize/mtcnn_fance-recognize/main 2/video_classifer_model_1.pickle"
    detectors = net("onet")
    os.environ["CUDA_VISIBLE_DEVICES"] = '0'
    mtcnnDetector = MtcnnDetector(detectors=detectors, min_face_size=40, threshold=[0.9, 0.6, 0.7])
    data = pickle.loads(open(model_path,'rb').read())
    recognize(model_path=data)

该博客仅作学习记录,每天进步一点点

参考文献
MTCNN+Face_recognition实时人脸识别训练自己的数据/多进程实时视频人脸识别

你可能感兴趣的:(mtcnn结合face_recognition实现视频流中人脸实时识别)