InsightFace是一个用于2D和3D人脸分析的集成Python库。 InsightFace 有效地实现了各种最先进的人脸识别、人脸检测和人脸对齐算法,并针对训练和部署进行了优化。
项目地址:https://github.com/deepinsight/insightface
截止本博文发布日,项目Star数达20k。
环境:ubuntu18 cuda11.7
pip install insightface
GPU:
pip install onnxruntime-gpu
CPU:
pip install onnxruntime
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等模型。
运行结果:
参考基于insightface实现的人脸识别和人脸注册
博主已经写的很详细了,而且可以拿来直接用,已测试。
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:[email protected].*.*/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。