一、项目简介
InsightFace是一个用于2D和3D人脸分析的集成Python库。 InsightFace 有效地实现了各种最先进的人脸识别、人脸检测和人脸对齐算法,并针对训练和部署进行了优化。
项目地址:https://github.com/deepinsight/insightface
截止本博文发布日,项目Star数达20k。
二、项目安装
环境:ubuntu18 cuda11.7
1、安装insightface
pip install insightface
2、安装onnxruntime
GPU:
pip install onnxruntime-gpu
CPU:
pip install onnxruntime
三、项目运行
1、官方示例
import cv2 import numpy as np import insightface from insightface.app import FaceAnalysis from insightface.data import get_image as ins_get_image app = FaceAnalysis(root='./',allowed_modules=['detection'],providers=['CUDAExecutionProvider', 'CPUExecutionProvider'],download=False) app.prepare(ctx_id=0, det_size=(640, 640)) img = ins_get_image('t1') #不用带后缀,图片放到./insightface/python-package/insightface/data/images faces = app.get(img) print("faces::::", faces) print("len:", len(faces)) rimg = app.draw_on(img, faces) cv2.imwrite("./ldh_out put.jpg", rimg) cv2.imshow("frame", rimg) if cv2.waitKey(0) & 0xFF == ord('Q'): cv2.destroyAllWindows()
运行后,会自动从github下载模型到当前项目models目录下,也可以手动下载,放置models目录
其中包含了检测人脸特征landmark、检测人脸、检测性别年龄、检测人脸特征embedding等模型。
运行结果:
2、人脸识别demo
参考基于insightface实现的人脸识别和人脸注册
博主已经写的很详细了,而且可以拿来直接用,已测试。
3、从摄像头获取视频进行人脸识别
import os import cv2 import insightface import numpy as np from sklearn import preprocessing import time import uuid class FaceRecognition: def __init__(self, gpu_id=0, face_db='face_db', threshold=1.24, det_thresh=0.7, 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_id self.face_db = face_db self.threshold = threshold self.det_thresh = det_thresh self.det_size = det_size # 加载人脸识别模型,当allowed_modules=['detection', 'recognition']时,只单纯检测和识别 self.model = insightface.app.FaceAnalysis(root='./', allowed_modules=None, 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 }) # 人脸识别 # 通过欧氏距离来对比人脸库中的人脸特征,默认如何它们的欧氏距离小于1.24,我们就可以认为他们是同一个人 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) face_info = {} 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"] face_info["user_name"] = user_name # 获取人脸属性 face_info["bbox"] = np.array(face.bbox).astype(np.int32).tolist() results.append(face_info) return results # 欧氏距离计算方式 @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 face_recognitio_webcam(): # 获取视频流 video_capture = cv2.VideoCapture("rtsp://admin:mima@192.168.*.*/h264/ch1/main/av_stream") # 加载人脸库 face_recognitio = FaceRecognition(face_db='known_people') dump_frame = 5 # 跳4帧 count_frame = 1 while True: # 抓取一帧视频 ret, frame = video_capture.read() count_frame += 1 if count_frame % dump_frame != 0: pass else: # 人脸识别 #beginTime = time.time() results = face_recognitio.recognition(frame) for face_info in results: name = face_info['user_name'] print(f"识别结果:{name}") top = face_info['bbox'][1] right = face_info['bbox'][2] bottom = face_info['bbox'][3] left = face_info['bbox'][0] pic_name = "face_imgs/"+ name + str(uuid.uuid1()) +".jpg" # 在脸周围画一个框 cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2) # 在脸下面画一个带名字的标签 cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED) font = cv2.FONT_HERSHEY_DUPLEX cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1) cv2.imwrite(pic_name, frame) # 并把图片保存到路径的文件夹 print('save face pic :',pic_name) #print(f'face_recognitio Done. ({time.time() - beginTime:.3f}s)') # 打印时间 cv2.imshow('Video', cv2.resize(frame,(1280,720))) # Hit 'q' on the keyboard to quit! if cv2.waitKey(1) & 0xFF == ord('q'): break if __name__ == '__main__': face_recognitio_webcam()
四、项目运行中问题记录
警告:
/home/ubuntu/anaconda3/envs/pytorch/lib/python3.8/site-packages/insightface/utils/transform.py:68: FutureWarning: `rcond` parameter will change to the default of machine precision times ``max(M, N)`` where M and N are the input matrix dimensions. To use the future default and silence this warning we advise to pass `rcond=None`, to keep using the old, explicitly pass `rcond=-1`. P = np.linalg.lstsq(X_homo, Y)[0].T # Affine matrix. 3 x 4
解决:定位到该代码段,改为 P = np.linalg.lstsq(X_homo, Y,rcond=None)[0].T 或者 P = np.linalg.lstsq(X_homo, Y,rcond=-1)[0].T。