MTCNN结合Face_recognition实现图片中人脸识别

一、 本文的结构

1、算法相关库的安装
2、底库文件生成
3、人脸识别
其中需要用到训练好的mtcnn模型,文中博主直接使用已经训练好的mtcnn模型

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

创建虚拟环境:

conda create -n face_recognize python=3.5

1. mtcnn环境配置
在新创建的环境中安装:

pip install tensorflow-gpu==1.14
pip install opencv-python

将训练好的mtcnn人脸检测代码放入project中
2. face-recognition依赖库安装
在环境中安装:

pip install cmake
pip install easydict
pip install scikit-learn==0.21.3
pip install Pillow 
pip install dlib
pip install face-recognition-models 

源码下载face-recognition代码

git clone https://github.com/ageitgey/face_recognition.git

三、 底库文件生成

1、该部分代码为生成人脸识别算法的底库文件,首先准备数据,数据集文件格式如下图文件夹结构所示:
在这里插入图片描述
图中每个文件夹代表一个类别,每个类别中放置几张图片,
运行代码后生成clf文件,用以下一部分的人脸识别;
代码:face_pic_classfier.py

# coding:utf-8
import os
import face_recognition
from sklearn import neighbors
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_folderdef 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 modelmodelPath = 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 detectorsdef train(train_dir, save_model_path=None, n_neighbors=None,knn_algo='ball_tree'):X = []y = []for class_file in os.listdir(train_dir):a = os.path.isdir(os.path.join(train_dir, class_file))if not a:continuefor image_path in image_files_in_folder(os.path.join(img_path, class_file)):print(image_path)pic_list = []face_location = []pic_list.append(image_path)testDatas = TestLoader(pic_list)allBoxs, _ = mtcnnDetector.detect_face(test_data=testDatas)for box in allBoxs[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("not suitable for trianing")else:image = face_recognition.load_image_file(image_path)face_encodings = face_recognition.face_encodings(image, known_face_locations=face_location, num_jitters=1)X.append(face_encodings[0])y.append(class_file)"""knn模块"""if n_neighbors is not None:print("n_neighbors is suitable")if False:print("no n_neighbors")knn_clf = neighbors.KNeighborsClassifier(n_neighbors=n_neighbors, algorithm=knn_algo, weights='distance')knn_clf.fit(X, y)if save_model_path is not None:with open(save_model_path, 'wb') as f:pickle.dump(knn_clf, f)return knn_clfif __name__ == '__main__':img_path = '/home/alex/face_recognize/mtcnn_fance-recognize/datasets'save_model_path = 'LFWTest_classifer_model.clf'detectors = net('onet')mtcnnDetector = MtcnnDetector(detectors=detectors, min_face_size=40, threshold=[0.9, 0.6, 0.7])classfier = train(train_dir=img_path, save_model_path=save_model_path, n_neighbors=2)

code的思路是,使用mtcnn对图片中的人脸进行定位,输出人脸的location,然后见location传递给face_recognition的face_encoding模块,对人脸进行128维的特征提取,然后使用KNN分类器,最后生成.clf文件

四、 MTCNN算法与face-recognition算法结合实现图片中的人脸识别

mtcnn_face_recognize_pic.py

# coding:#utf-8
import os
import face_recognition
import pickle
import cv2
# 加载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_folderdef 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 modelmodelPath = 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 detectorsdef predict(train_dir, model_path ,distance_threshold=0.45):pic_list = []face_location = []pic_list.append(train_dir)testDatas = TestLoader(pic_list)allBoxs, _ = mtcnnDector.detect_face(testDatas)for box in allBoxs[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(allBoxs[0]) == 0:print('no face in the pic')return []image = face_recognition.load_image_file(train_dir)face_encodings = face_recognition.face_encodings(image, known_face_locations=face_location, num_jitters=3)"""knn模块"""with open(model_path, 'rb') as f:knn_clf = pickle.load(f)close_distance = knn_clf.kneighbors(face_encodings, n_neighbors=1)are_match = [close_distance[0][i][0] <= distance_threshold for i in range(len(face_location))]return [(pred, loc) if rec else ("unknown", loc) for pred, loc, rec in zip(knn_clf.predict(face_encodings), face_location, are_match)]def show_result(image_path, predictions):image= cv2.imread(image_path)for name, (top, right, bottom, left) in predictions:cv2.putText(image, str(name), (left, top-10), cv2.FONT_HERSHEY_TRIPLEX, 1, color=(0,255,0))cv2.rectangle(image,(left, top), (right, bottom),color=(0, 255, 0), thickness=2)cv2.imwrite(str(image_path) + '.jpg', image)cv2.imshow('result', image)cv2.waitKey(400)cv2.destroyAllWindows()if __name__ == '__main__':image_path = "/home/alex/face_recognize/mtcnn_fance-recognize/datasets/alan_grant"model_path ="/home/alex/face_recognize/mtcnn_fance-recognize/main 2/LFWTest_classifer_model"detectors = net('onet')mtcnnDector = MtcnnDetector(detectors=detectors, min_face_size=40, threshold=[0.9, 0.6, 0.7])for img_file in os.listdir(image_path):full_img_path = os.path.join(image_path, img_file)predictions = predict(train_dir=full_img_path, model_path=model_path)show_result(full_img_path, predictions)

code的思路,首先将图片以局对路径输入到mtcnn模块中对人脸进行定位,输出图片中人脸的location,然后将图片location输入face_recognition模块中提取图片的128维特征,输出encoding,使用KNN算法计算最佳距离,最后与底库中的encoding比对并输出结果

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

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


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部