import cv2
import insightface
import numpy as np
from sklearn import preprocessing
import os
# 初始化操作
app = insightface.app.FaceAnalysis(name="buffalo_l",provider = ["CPUExecutionProvider"])
app.prepare(ctx_id=-1,det_size=(640,640))
face_info = {}
face_similarity = {}
def register():
face_path = "face_db" # 用于存储人脸的嵌入特征
files = os.listdir(face_path)
for file in files:
username = file.split('.')[0]
print(file)
face_img = cv2.imdecode(np.fromfile("face_db"+'/'+file, dtype=np.uint8,)-1)
face = app.get(face_img)
embedding = np.array(face[0].embedding).reshape((1, -1))
embedding = preprocessing.normalize(embedding)
face_info.update({username: embedding})
print(f"{username}--xxx人脸识别完毕")
def face_check():
cap = cv2.VideoCapture(0) # 打开默认摄像头
while True:
ret, frame = cap.read()
if not ret:
break # 如果读取失败,则退出循环
# 使用app(FaceAnalysis实例)检测帧中的人脸
unknow_faces = app.get(frame) # 假设app.get()返回的是一个包含多个FaceInfo对象的列表
if unknow_faces:
unknow_face = unknow_faces[0]
unknow_embedding = np.array(unknow_face.embedding).reshape((1, -1))
unknow_embedding = preprocessing.normalize(unknow_embedding)
face_similarity = {} # 初始化相似度字典,每次循环都重新创建
for k, v in face_info.items():
similarity = similar(unknow_embedding, v)
face_similarity[k] = similarity
max_similarity = max(face_similarity, key=face_similarity.get)
if face_similarity[max_similarity] > 0.5:
# 如果最高相似度大于0.5,则显示识别到的人名
cv2.putText(frame, f"识别到:{max_similarity}", (100, 30), 2, cv2.FONT_HERSHEY_PLAIN, 1, 2)
cv2.putText(frame, str(face_similarity[max_similarity]), (300, 30), 2, cv2.FONT_HERSHEY_PLAIN, 1, 2)
else:
# 否则,显示“系统不识别此人”
cv2.putText(frame, "系统不识别此人", (100, 30), 2, cv2.FONT_HERSHEY_PLAIN, 1, 2)
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break # 按'q'键退出循环
cap.release() # 释放摄像头
cv2.destroyAllWindows() # 关闭所有OpenCV创建的窗口
# 注意:相似度计算函数similar和绘制函数draw需要在此函数外部定义
def similar(a,b):
dot_a_b =np.dot(a,b.T)
norm_a = np.linalg.norm(a)
norm_b = np.linalg.norm(b)
cosine_similarity = dot_a_b / (norm_a *norm_b)
return cosine_similarity
def draw(img):
faces = app.get(img)
for face in faces:
bbox = face.bbox.astype(int)
cv2.rectangle(img, (bbox[0], bbox[1]), (bbox[2], bbox[3]), (0, 255, 0), 2)
for k in face.landmark_3d_68:
x, y, z = k.astype(int)
cv2.circle(img, (x, y), 1, (255, 255, 255), 2)
if "__main__"==__name__:
while True:
print("---输入1:进行人脸注册---")
print("---输入2:进行人脸验证---")
print("---输入其他字符程序结束---")
user_need = input("请选择你需要执行的操作:")
if user_need =="1":
register()
elif user_need =="2":
print("即将进入身份验证")
face_check()
else:
print("程序结束")
基于insightface进行人脸1:N
于 2024-07-03 21:51:22 首次发布