import abc
import os
from typing import List, Tuple
import dlib
import numpy as np
from src.util import Util
[文档]class FaceEncoding(metaclass=abc.ABCMeta):
"""
人脸特征值提取face encoding抽象类
"""
[文档] @staticmethod
@abc.abstractmethod
def encoding_frame_box(frame_box) -> List[Tuple[str, str, str, str]]:
"""
获取frame_box中头像和对应box位置的特征码
:param frame_box: frame_box,包含了图片和box信息
"""
pass
[文档] @staticmethod
@abc.abstractmethod
def encoding(img, box):
"""
获取图片中头像的特征码
:param img: 图片,h,w,s三维信息
:param box: 头像坐标
"""
pass
[文档] @staticmethod
@abc.abstractmethod
def encoding_img(face_img):
"""
获取图片中第一个头像的特征码(言外之意,图片本来就是头像图片)
:param face_img: 图片,h,w,s三维信息
"""
pass
[文档]class FaceEncodingFrFe(FaceEncoding):
[文档] @staticmethod
def encoding_frame_box(frame_box):
if frame_box.img is not None and len(frame_box.img) > 0 and frame_box.box is not None and len(
frame_box.box) > 0:
return FaceEncodingFrFe.encoding(frame_box.img, frame_box.box)
return FaceEncodingFrFe.encoding_img(frame_box.img)
[文档] @staticmethod
def encoding(img, box):
fl_box = Util.cv_to_fl_box(box)
face_encodings = face_recognition.face_encodings(img, [fl_box])
return np.array(face_encodings[0]) if face_encodings else None
[文档] @staticmethod
def encoding_img(face_img):
face_encodings = face_recognition.face_encodings(face_img)
return np.array(face_encodings[0]) if face_encodings else None
[文档]class FaceEncodingDlibReg(FaceEncoding):
face_detector = dlib.get_frontal_face_detector()
shape = dlib.shape_predictor( os.path.normpath('%s/%s' % (os.path.dirname(__file__), "../model/shape_predictor_68_face_landmarks.dat")))
face_encoding = dlib.face_recognition_model_v1( os.path.normpath('%s/%s' % (os.path.dirname(__file__), "../model/dlib_face_recognition_resnet_model_v1.dat")))
[文档] @staticmethod
def cv_box_to_dlib(box):
x, y, w, h = box
rectangle = dlib.rectangle(x, y, x + w, y + h)
return rectangle
[文档] @staticmethod
def encoding_frame_box(frame_box):
if frame_box.img is not None and len(frame_box.img) > 0 and frame_box.box is not None and len(
frame_box.box) > 0:
return FaceEncodingDlibReg.encoding(frame_box.img, frame_box.box)
return FaceEncodingDlibReg.encoding_img(frame_box.img)
[文档] @staticmethod
def encoding(img, box):
rectangle = FaceEncodingDlibReg.cv_box_to_dlib(box)
shape = FaceEncodingDlibReg.shape(img, rectangle)
face_descriptor = FaceEncodingDlibReg.face_encoding.compute_face_descriptor(img, shape)
return np.array(face_descriptor)
[文档] @staticmethod
def encoding_img(face_img):
boxes = FaceEncodingDlibReg.face_detector(face_img, 1)
if not boxes:
return None
box = boxes[0]
shape = FaceEncodingDlibReg.shape(face_img, box)
face_descriptor = FaceEncodingDlibReg.face_encoding.compute_face_descriptor(face_img, shape)
return np.array(face_descriptor)
[文档]class FaceEncodingFactory(object):
"""
face encoding 的工厂类
"""
face_encoding_construct = {"FR_FE": FaceEncodingFrFe,
"DLIB_REG": FaceEncodingDlibReg}
[文档] @staticmethod
def get_instance(encoding_method):
"""
获取encoding_method对应的encoding实例
:param encoding_method: 人脸特征码提取方法
:return: 特征码提取方法实例
"""
return FaceEncodingFactory.face_encoding_construct.get(encoding_method)()