参考:https://huaweicloud.csdn.net/638088d7dacf622b8df89c0c.html
insightface模型下载可能需要连接外网,模型自动下载保存再models\buffalo_l下,人脸注册自动保存再face_db目录下
1、具体人脸录入
python face_label.py --picture 刘亦菲.jpg --register Ture
python face_label.py --picture 杨幂.jpg --register Ture
(运行后会把照片保存一份到face_db目录下)
2、具体检测识别人脸
python face_label.py --picture 11.jpg --recognition Ture (11.jpg是一种杨幂照片)
运行后结果:
如果检测的是face_db目录不存在的图片,这里找的一张黄晓明照片:
python face_label.py
–picture 22.jpg --recognition Ture
运行结果,结果未知默认显示unknown:
3、 一对多图像库检索加速
embedding是实时检测的单个人头像embedding,可以
## 单个人头像embedding
embedding = np.array(face.embedding).reshape((1, -1))
embedding = preprocessing.normalize(embedding)
## 图库里所以图片faces_embeddings
for file in files:input_image = cv2.imdecode(np.fromfile(os.path.join(root, file), dtype=np.uint8), 1)user_name = file.split(".")[0]face = self.model.get(input_image)[0]embedding = np.array(face.embedding).reshape((1, -1))embedding = preprocessing.normalize(embedding)faces_embedding.append({"user_name": user_name,"feature": embedding})
faces_embeddings = []
for com_face in faces_embedding:faces_embeddings.append(com_face["feature"])
计算相似度:
print(“cosine”, (faces_embeddings @ embedding.T))
代码
face_label.py 代码
import osimport cv2
import insightface
import numpy as np
from sklearn import preprocessing
import argparseclass FaceRecognition:def __init__(self, gpu_id=0, face_db='face_db', threshold=1.24, det_thresh=0.50, det_size=(640, 640)):"""人脸识别工具类:param gpu_id: 正数为GPU的ID,负数为使用CPU:param face_db: 人脸库文件夹:param threshold: 人脸识别阈值:param det_thresh: 检测阈值:param det_size: 检测模型图片大小"""self.gpu_id = gpu_idself.face_db = face_dbself.threshold = thresholdself.det_thresh = det_threshself.det_size = det_size# 加载人脸识别模型,当allowed_modules=['detection', 'recognition']时,只单纯检测和识别self.model = insightface.app.FaceAnalysis(root='./',# allowed_modules=None,allowed_modules=['detection', 'recognition'],providers=['CUDAExecutionProvider'])self.model.prepare(ctx_id=self.gpu_id, det_thresh=self.det_thresh, det_size=self.det_size)# 人脸库的人脸特征self.faces_embedding = list()# 加载人脸库中的人脸self.load_faces(self.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_name = 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_name": user_name,"feature": embedding})# 人脸识别def recognition(self, image):faces = self.model.get(image)results = list()for face in faces:# 开始人脸识别embedding = np.array(face.embedding).reshape((1, -1))embedding = preprocessing.normalize(embedding)user_name = "unknown"for com_face in self.faces_embedding:r = self.feature_compare(embedding, com_face["feature"], self.threshold)if r:user_name = com_face["user_name"]results.append(user_name)return results@staticmethoddef feature_compare(feature1, feature2, threshold):diff = np.subtract(feature1, feature2)dist = np.sum(np.square(diff), 1)if dist < threshold:return Trueelse:return Falsedef register(self, image, user_name):faces = self.model.get(image)if len(faces) != 1:return '图片检测不到人脸'# 判断人脸是否存在embedding = np.array(faces[0].embedding).reshape((1, -1))embedding = preprocessing.normalize(embedding)is_exits = Falsefor com_face in self.faces_embedding:r = self.feature_compare(embedding, com_face["feature"], self.threshold)if r:is_exits = Trueif is_exits:return '该用户已存在'# 符合注册条件保存图片,同时把特征添加到人脸特征库中cv2.imencode('.png', image)[1].tofile(os.path.join(self.face_db, '%s.png' % user_name))self.faces_embedding.append({"user_name": user_name,"feature": embedding})return "success"# 检测人脸def detect(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()# result["kps"] = np.array(face.kps).astype(np.int32).tolist()# print(np.array(face.landmark_3d_68))# result["landmark_3d_68"] = np.array(face.landmark_3d_68).astype(np.int32).tolist()# result["landmark_2d_106"] = np.array(face.landmark_2d_106).astype(np.int32).tolist()# result["pose"] = np.array(face.pose).astype(np.int32).tolist()# result["age"] = face.age# gender = '男'# if face.gender == 0:# gender = '女'# result["gender"] = gender# 开始人脸识别embedding = np.array(face.embedding).reshape((1, -1))embedding = preprocessing.normalize(embedding)result["embedding"] = embeddingresults.append(result)return resultsif __name__ == '__main__':parser = argparse.ArgumentParser()parser.add_argument('--picture', type=str,help="picture adress")# parser.add_argument('--name', type=str,help="user name")parser.add_argument('--register', default=False,help="people register")parser.add_argument('--recognition', default=False,help="people recognition")args = parser.parse_args()# print(args.picture,args.picture.split(".")[0])if args.register:img = cv2.imdecode(np.fromfile(args.picture, dtype=np.uint8), -1)face_recognitio = FaceRecognition()# 人脸注册 录入保存result = face_recognitio.register(img, user_name=args.picture.split(".")[0])print(result) if args.recognition:img = cv2.imdecode(np.fromfile(args.picture, dtype=np.uint8), -1)face_recognitio = FaceRecognition()# 人脸识别results = face_recognitio.recognition(img)for result in results:print("识别结果:{}".format(result))results = face_recognitio.detect(img)for result in results:print('人脸框坐标:{}'.format(result["bbox"]))# print('人脸五个关键点:{}'.format(result["kps"]))# print('人脸3D关键点:{}'.format(result["landmark_3d_68"]))# print('人脸2D关键点:{}'.format(result["landmark_2d_106"]))# print('人脸姿态:{}'.format(result["pose"]))# print('年龄:{}'.format(result["age"]))# print('性别:{}'.format(result["gender"]))