# -*- coding:utf-8 -*- """ @Created on : 2023/3/10 18:49 @Author: hxl @Des: """ from io import BytesIO import cv2 from arcsoft.engine import * from arcsoft.struct_info import ASF_SingleFaceInfo from conf import setting from .exception import ArcSoftCallException, NonLivingException, FaceNotFoundException, FaceMoreThanOneException, UserNotFoundException class FaceRecognitionEngine: def __init__(self): self.app_id = bytes(setting.ARCSOFT_APP_ID, 'utf-8') self.sdk_key = bytes(setting.ARCSOFT_SDK_KEY, 'utf-8') def __enter__(self): face_engine = ArcFace() face_engine.ASFInitEngine(ASF_DETECT_MODE_IMAGE, ASF_OP_0_ONLY, 30, 5, ASF_FACE_DETECT | ASF_FACERECOGNITION | ASF_LIVENESS) self.face_engine = face_engine return self def __exit__(self, type, value, trace): # 销毁引擎 self.face_engine.ASFUninitEngine() # 虹软库激活 def activation(self) -> bool: ack = ASFOnlineActivation(self.app_id, self.sdk_key) return (MOK == ack or MERR_ASF_ALREADY_ACTIVATED == ack) # 获取人脸特征信息 def feature(self, buffer): face_feature = self.gen_face_feature(buffer) if face_feature: data = BytesIO(string_at(face_feature.feature, face_feature.featureSize)) return data.getvalue() # 人脸登入 def login(self, buffer, users): face_feature = self.gen_face_feature(buffer) # 获取人脸特征信息 if face_feature: for u in users: face_encode = self.face_engine.ASFGetFeatureFromBinary(u[1]) ack, score = self.face_engine.ASFFaceFeatureCompare(face_feature, face_encode) if ack == 0: if score >= setting.FACE_RECOGNITION_THRESHOLD: return u[0] # 返回用户id # face_encodes = [self.face_engine.ASFGetFeatureFromBinary(u[1]) for u in users] # for index, face_encode in enumerate(face_encodes): # ack, score = self.face_engine.ASFFaceFeatureCompare(face_feature, face_encode) # if ack == 0: # if score >= setting.FACE_RECOGNITION_THRESHOLD: # return users[index][0] # 返回用户id else: raise UserNotFoundException() else: raise FaceNotFoundException() def gen_face_feature(self, frame): sp = frame.shape frame = cv2.resize(frame, (sp[1] // 4 * 4, sp[0])) # 四字节对齐 ack, detect_faces = self.face_engine.ASFDetectFaces(frame) # 检测图中的人脸 if MOK != ack: raise ArcSoftCallException() if detect_faces.faceNum < 1: raise FaceNotFoundException() if detect_faces.faceNum > 1: raise FaceMoreThanOneException() ack = self.face_engine.ASFProcess(frame, detect_faces, ASF_LIVENESS) if MOK != ack: raise ArcSoftCallException() # 非活体检测取消 # ack, liveness = self.face_engine.ASFGetLivenessScore() # if MOK != ack: # raise ArcSoftCallException() # # if liveness.isLive[0] == 0: # raise NonLivingException() if MOK == ack: single_detected_face = ASF_SingleFaceInfo() single_detected_face.faceRect = detect_faces.faceRect[0] single_detected_face.faceOrient = detect_faces.faceOrient[0] ack, face_feature = self.face_engine.ASFFaceFeatureExtract(frame, single_detected_face) if MOK != ack: raise ArcSoftCallException() return face_feature