研究了人脸识别,人脸识别分为人脸检测和人脸比对,模型选用insightface训练的模型
下载模型到本地使用,关于使用本地模型文件参考快速InsightFace和InsightFace Paddle学习与实践 - 知乎 (zhihu.com) 修改文件
work/insightface/python-package/insightface/app/face_analysis.py
work/insightface/python-package/insightface/app/mask_renderer.py
work/insightface/python-package/insightface/model_zoo/model_zoo.py
如
class FaceAnalysis:
def __init__(self, name=DEFAULT_MP_NAME, root='~/work/.insightface', allowed_modules=None, **kwargs):
文件位置参考C:\Users\CT080120\work.insightface\models\buffalo_l.zip
检测和比对应用实现参考基于insightface实现的人脸识别和人脸注册-腾讯云开发者社区-腾讯云 (tencent.com)
pip install insightface
pip install onnxruntime
核心
import cv2
import numpy as np
from insightface.app import FaceAnalysis
from sklearn import preprocessing
def det(src):
app = FaceAnalysis('buffalo_l', allowed_modules=['detection'])
app.prepare(ctx_id=-1, det_size=(640, 640))
img = cv2.imread(src)
faces = app.get(img)
rimg = app.draw_on(img, faces)
cv2.imwrite("./t1_output.jpg", rimg)
return faces
def reco():
app = FaceAnalysis('buffalo_l', allowed_modules=['detection', 'recognition'])
app.prepare(ctx_id=-1, det_size=(640, 640))
img = cv2.imread("./hezhao.png")
faces = app.get(img)
results = list()
for face in faces:
result = dict()
# 获取人脸属性
result["bbox"] = np.array(face.bbox).astype(np.int32).tolist()
# 开始人脸识别
embedding = np.array(face.embedding).reshape((1, -1))
embedding = preprocessing.normalize(embedding)
results.append(result)
if __name__ == '__main__':
det("./danren.png")
# reco()
完整 FaceRecognition.py
import os
from random import choice
import cv2
import insightface
import numpy as np
from sklearn import preprocessing
from DeployConfig import DeployConfig
class FaceRecognition:
def __init__(self, conf_file):
self.config = DeployConfig(conf_file)
# 加载人脸识别模型
self.model = insightface.app.FaceAnalysis('buffalo_l', allowed_modules=['detection', 'recognition'])
self.model.prepare(ctx_id=self.config.gpu_id, det_thresh=self.config.nms)
# 人脸库的人脸特征
self.faces_embedding = list()
# 加载人脸库中的人脸
self.load_faces(self.config.face_db)
# 加载人脸库中的人脸
def load_faces(self, face_db_path):
if not os.path.exists(face_db_path):
os.makedirs(face_db_path)
for root, dirs, files in os.walk(face_db_path):
for file in files:
input_image = cv2.imdecode(np.fromfile(os.path.join(root, file), dtype=np.uint8), 1)
user_id = file.split(".")[0]
face = self.model.get(input_image)[0]
embedding = np.array(face.embedding).reshape((1, -1))
embedding = preprocessing.normalize(embedding)
self.faces_embedding.append({
"user_id": user_id,
"feature": embedding
})
@staticmethod
def feature_compare(feature1, feature2, threshold):
diff = np.subtract(feature1, feature2)
dist = np.sum(np.square(diff), 1)
if dist < threshold:
return True
else:
return False
def register(self, image):
faces = self.model.get(image)
if len(faces) != 1:
return None
# 判断人脸是否存在
embedding = np.array(faces[0].embedding).reshape((1, -1))
embedding = preprocessing.normalize(embedding)
is_exits = False
for com_face in self.faces_embedding:
r = self.feature_compare(embedding, com_face["feature"], self.config.threshold)
if r:
is_exits = True
if is_exits:
return None
old_user_id = [d["user_id"] for d in self.faces_embedding]
user_id = self.get_user_id(old_user_id)
# 符合注册条件保存图片,同时把特征添加到人脸特征库中
cv2.imencode('.png', image)[1].tofile(os.path.join(self.config.face_db, '%s.png' % user_id))
self.faces_embedding.append({
"user_id": user_id,
"feature": embedding
})
return user_id
def get_user_id(self, old_user_id):
print(old_user_id)
while True:
user_id = "".join([choice("0123456789ABCDEF") for i in range(8)])
if user_id not in old_user_id:
break
return user_id
def recognition(self, image):
faces = self.model.get(image)
results = list()
for face in faces:
result = dict()
# 获取人脸属性
result["bbox"] = np.array(face.bbox).astype(np.int32).tolist()
# 开始人脸识别
embedding = np.array(face.embedding).reshape((1, -1))
embedding = preprocessing.normalize(embedding)
result["user_id"] = "unknown"
for com_face in self.faces_embedding:
r = self.feature_compare(embedding, com_face["feature"], self.config.threshold)
if r:
result["user_id"] = com_face["user_id"]
results.append(result)
return results
if __name__ == '__main__':
img = cv2.imread("danren.png")
img2 = cv2.imread("hezhao.png")
face_recognition = FaceRecognition("config.yaml")
user_id = face_recognition.recognition(img2)
print(user_id)
DeployConfig.py
import os
import yaml
# Deploy Configuration File Parser
class DeployConfig:
def __init__(self, conf_file):
if not os.path.exists(conf_file):
raise Exception('Config file path [%s] invalid!' % conf_file)
with open(conf_file) as fp:
configs = yaml.load(fp, Loader=yaml.FullLoader)
deploy_conf = configs["FACE"]
# 正数为GPU的ID,负数为使用CPU
self.gpu_id = deploy_conf["GPU_ID"]
self.face_db = deploy_conf["FACE_DB"]
self.threshold = deploy_conf["THRESHOLD"]
self.nms = deploy_conf["NMS"]
config.yaml
FACE:
GPU_ID: -1
FACE_DB: "face_db"
THRESHOLD: 1.24
NMS: 0.50