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)
实际的操作就是使用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实时人脸识别训练自己的数据/多进程实时视频人脸识别