尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

千人千面无人考评人脸验证算法实现

千人千面无人考评人脸验证算法实现 在无人考评系统的实际运行中为有效防范面部遮挡、替考等违规行为系统需对考生进行持续的面部身份核验。该过程依赖于两项核心算法的协同工作人脸检测定位算法与人脸特征比对算法。算法模型对比这里我们首先进行人脸检测定位算法的介绍我们的人脸检测算法共有两个分别是face_recognition库中自带的face_locations方法与YOLO-face其两者对比如下维度face_recognition(基于 dlib)YOLO目标检测 (YOLOv8-Face)核心定位轻量级、开箱即用的人脸识别库工业级、高性能的目标检测算法检测速度较慢HOG 模式约 30-50msCNN 模式 CPU 下 300ms极快GPU 加速下可达 100 FPS满足实时流处理检测精度与鲁棒性一般。对正脸、清晰度、光照要求高大角度侧脸、遮挡、密集人群易漏检或框飘极高。对极端光照、大角度偏转、口罩遮挡、小目标及密集人群具有极强适应性小目标检测能力较弱默认参数下远距离小脸易漏检强通过特征金字塔等技术能精准捕获远景模糊小脸环境配置与部署极简。API 封装度高兼容性好适合快速原型开发较复杂。需配置深度学习环境PyTorch/TensorRT模型体积相对较大硬件依赖CPU 友好HOG 模式CNN 模式强依赖 GPU强依赖 GPU 算力纯 CPU 推理延迟高无法发挥速度优势附加功能内置 128 维特征向量提取用于身份识别及 68 个面部关键点定位专注目标检测输出边界框需结合其他模型进行特征提取或关键点定位在无人考评中的角色准入阶段高门槛严筛利用其对正脸和清晰度的严苛要求增加开考验证难度拦截照片翻拍及不良环境考试阶段高鲁棒稳控利用其极低的延迟和强鲁棒性保障长时段考试中考生姿态变换、遮挡情况下的监控连续性同样的我们的人脸识别方法也有两个分别是face_recognition自带的face_encodings方法以及SFace模型两种对比如下维度SFace (OpenCV)face_recognition (dlib)识别精度高抗遮挡、跨年龄、低分辨率表现好跨年龄准确率可达96.8%一般LFW数据集准确率约99.3%复杂场景如大角度侧脸、严重遮挡易失效运行性能极快毫秒级响应适合实时视频流处理较慢CPU下单张处理约100-200ms实时性差高并发受限代码复杂度中等需手动组合人脸检测、对齐、特征提取及相似度计算流水线极低API极简一行代码即可提取128维特征向量开箱即用环境部署简单基于ONNX格式与OpenCV跨平台部署友好无复杂依赖复杂依赖C库dlib在Windows或ARM架构上安装常遇编译报错与依赖冲突适用场景工业级应用如无人考评、安防监控、门禁考勤等对实时性与准确率要求高的场景快速原型开发如Demo验证、离线相册分类等对精度和实时性要求较低的场景SFace人脸识别模型工程设计在无人考评系统的身份核验环节采用“考前严准入、考中稳监控”的双轨制策略是兼顾系统安全性与工程性能的优化方案。在考前准入阶段系统选用face_recognition算法进行身份核验。该算法对人脸姿态和图像清晰度要求较为严苛这一特性恰好被转化为高标准的“准入壁垒”强制考生在良好的光线和端正的姿态下完成验证从而从源头上有效拦截照片翻拍等初级作弊手段并确保初始人脸特征库的高质量。而在考试进行阶段考虑到考生不可避免地会出现低头、侧脸或光线变化等动态情况系统则切换为“YOLO SFace”的组合架构。YOLO算法凭借其在复杂场景下极强的检测能力能够精准捕捉非标准姿态下的人脸目标SFace则在特征提取与比对上具备高精度与低延迟的优势。通过每隔固定帧进行抽帧核验该组合不仅保障了长时段监控的连续性避免了逐帧检测带来的算力浪费还大幅提升了系统在真实考场环境下的鲁棒性。这种“静态严审 动态宽控”的混合架构完美解决了单一算法难以兼顾高安全性与高实时性的工程痛点是兼顾业务逻辑与底层算法特性的最优落地方案算法推理实现当我们使用face_recognition库时直接调用face_locations与face_encodings方法即可代码如下defrecognize_from_frame(self,frame:np.ndarray)-Optional[Tuple[int,str,float]]:ifnotself._initializedorlen(self.known_encodings)0:returnNonetry:# BGR转RGBrgb_framecv2.cvtColor(frame,cv2.COLOR_BGR2RGB)# 检测人脸位置face_locationsface_recognition.face_locations(rgb_frame)ifnotface_locations:returnNone# 计算当前帧中人脸的编码face_encodingsface_recognition.face_encodings(rgb_frame,face_locations)ifnotface_encodings:returnNone# 只处理第一张人脸current_encodingface_encodings[0]# 与已知人脸比对distancesface_recognition.face_distance(self.known_encodings,current_encoding)# 找到最佳匹配best_match_indexnp.argmin(distances)best_distancedistances[best_match_index]# 设置匹配阈值TOLERANCE0.3ifbest_distanceTOLERANCE:nameself.known_names[best_match_index]confidencemax(0,min(100,(1-best_distance/TOLERANCE)*100))return(best_match_index,name,confidence)returnNoneexceptExceptionase:print(f[FaceRecognizer] 人脸识别出错:{e})returnNoneYOLO-Face目标检测模型的训练结果显示其在极端场景下的综合性能表现一般。然而考虑到无人考评的实际业务场景主要以单一大尺度人脸为主小目标及密集人脸等长尾情况出现频率极低。因此从实际项目落地的角度评估该模型的检测效果完全能够满足业务需求。在考试过程中的人脸识别算法就较为复杂了其要将YOLO与SFace进行结合首先是利用YOLO识别人脸定位到人脸位置defdetect_faces_yolo(self,image):img_rgbcv2.cvtColor(image,cv2.COLOR_BGR2RGB)img_letter,ratio,(pad_w,pad_h)letterbox(img_rgb,(self.input_h,self.input_w))img_normimg_letter.astype(np.float32)/255.0input_tensornp.expand_dims(img_norm.transpose(2,0,1),axis0)outputsself.session_det.run(None,{self.input_name:input_tensor})predictionsnp.squeeze(outputs[0]).Tifpredictions.size0:return[]scoresnp.max(predictions[:,4:],axis1)maskscoresself.conf_thresifnotnp.any(mask):return[]predictionspredictions[mask]scoresscores[mask]class_idsnp.argmax(predictions[:,4:],axis1)boxes_xywhpredictions[:,:4]# 1. 去填充boxes_xywh[:,0]-pad_w boxes_xywh[:,1]-pad_h boxes_xywh[:,:4]/ratio boxes_xyxyxywh2xyxy(boxes_xywh)indicesmulticlass_nms(boxes_xyxy,scores,class_ids,self.iou_thres)iflen(indices)0:return[]final_boxesboxes_xyxy[indices]iflen(final_boxes)0:# 1. 获取画面的宽高和中心点坐标h,wimage.shape[:2]center_x,center_yw/2,h/2# 2. 计算每个检测框的中心点box_centers_x(final_boxes[:,0]final_boxes[:,2])/2box_centers_y(final_boxes[:,1]final_boxes[:,3])/2# 3. 计算各个框中心点到画面中心点的欧几里得距离平方即可无需开根号distances(box_centers_x-center_x)**2(box_centers_y-center_y)**2# 4. 找出距离最小的那个框的索引并只返回这一个框nearest_idxnp.argmin(distances)return[final_boxes[nearest_idx]]return[]随后在使用SFace模型进行特征提取这里需要注意的是为了达到最佳的识别效果并且保证鲁棒性在提取到人脸的ROI区域后需要将其进行尺度变换rec_blobself._preprocess(face_img,(112,112))这是由于112×112是SFace模型在预训练阶段设定的标准尺寸随后利用SFace进行特征提取并与先前的人脸特征进行比对这里我采用的是欧式距离与余弦相似度相结合的方式判定相似度forfaceinfaces:x1,y1,x2,y2face x1,y1,x2,y2int(x1),int(y1),int(x2),int(y2)ifself.ref_embeddingisnotNone:face_imgframe[y1:y2,x1:x2]ifface_img.size0:continue# 预处理并推理rec_blobself._preprocess(face_img,(112,112))featureself.session_rec.run(None,{rec_input_name:rec_blob})[0]current_featurefeature/np.linalg.norm(feature)# 计算余弦相似度scorenp.dot(current_feature,self.ref_embedding.T)[0][0]print(score,score)distancenp.linalg.norm(current_feature-self.ref_embedding)print(distance,distance)ifscorethresholdanddistancedistance_threshold:self.tikao_det_count0else:self.tikao_det_count1ifnotself.is_prompting:try:self.is_promptingTruewinsound.PlaySound(get_resource_path(./resources/wavs/tikao.wav),winsound.SND_FILENAME|winsound.SND_ASYNC|winsound.SND_NOWAIT)exceptExceptionase:print(e)这里我们加入了替考判定如果当前人脸与开始考试的人脸比对不通过那么进行语音提醒try:self.is_promptingTruewinsound.PlaySound(get_resource_path(./resources/wavs/no_face.wav),winsound.SND_FILENAME|winsound.SND_ASYNC|winsound.SND_NOWAIT)exceptExceptionase:print(e)工程实现针对传统单线程处理视频流时易引发的卡顿与掉帧等性能瓶颈本系统引入了基于“生产者-消费者”模型的多线程并发架构以显著提升系统的实时处理能力。该架构将处理流程解耦为四个核心模块采集线程作为数据生产者负责持续读取摄像头或视频流并将原始帧数据异步写入缓冲队列检测线程池采用多线程并行机制高效执行人体检测与人脸定位任务特征提取线程专注于图像预处理与特征工程依次完成人脸对齐、图像增强及特征向量提取身份匹配线程负责将提取的特征与底层人脸库进行比对并输出最终的身份判定结果。
返回列表