您的位置:首页 > 文旅 > 旅游 > 潍坊疫情最新消息今天新增病例_武汉建设公司的网站_品牌推广的具体方法_网站排名搜索

潍坊疫情最新消息今天新增病例_武汉建设公司的网站_品牌推广的具体方法_网站排名搜索

2024/10/6 6:01:04 来源:https://blog.csdn.net/Jiagym/article/details/142106951  浏览:    关键词:潍坊疫情最新消息今天新增病例_武汉建设公司的网站_品牌推广的具体方法_网站排名搜索
潍坊疫情最新消息今天新增病例_武汉建设公司的网站_品牌推广的具体方法_网站排名搜索

【人工智能学习之人脸识别】

  • 人脸识别思路
  • 人脸识别代码与讲解
    • 我的代码:
  • 效果图

人脸识别思路

因为人脸数据很不好找,训练也比较麻烦,所以我们可以直接使用现成的模型权重。

思路:人脸检测->特征提取->注册/识别

人脸检测可以选择又快又小效果还很棒的DBface克隆链接:DBFace

特征提取我选择的DeepFace中的Facenet512,读者也可以换成其它的模型或者自己训练的模型都可以,这里只做特征提取,所以我直接使用训练好的DeepFace中的Facenet512

有了识别网络和特征网络之后就只剩下后处理部分,我们可以设置待检测区域,只有单张人脸进入该区域,识别或注册程序才会启动。注册需要采集上下左右转头的人脸图像,登录则需要将检测区的人脸与特征库进行比对(比对方法可以采取欧氏距离或者余弦相似度)。

人脸识别代码与讲解

因为借用别人以及训练好的模型,直接导入DBFace和DeepFace使用即可。
不过首先你必须明白DBFace侦测网络返回的各个结果是什么意思,温馨提示:可以查看DBface的common.py。
common.py中的drawbbox中对bbox的使用有很强的参考性,它会让你明白返回的x, y, r, b分别是什么,以及你如何按照你的想法调整。

def drawbbox(image, bbox, color=None, thickness=2, textcolor=(0, 0, 0), landmarkcolor=(0, 0, 255)):if color is None:color = randcolor(bbox.label)#text = f"{bbox.label} {bbox.score:.2f}"text = f"{bbox.score:.2f}"x, y, r, b = intv(bbox.box)w = r - x + 1h = b - y + 1cv2.rectangle(image, (x, y, r-x+1, b-y+1), color, thickness, 16)border = thickness / 2pos = (x + 3, y - 5)cv2.rectangle(image, intv(x - border, y - 21, w + thickness, 21), color, -1, 16)cv2.putText(image, text, pos, 0, 0.5, textcolor, 1, 16)if bbox.haslandmark:for i in range(len(bbox.landmark)):x, y = bbox.landmark[i][:2]cv2.circle(image, intv(x, y), 3, landmarkcolor, -1, 16)

以及DeepFace中特征部分存储在哪一个字段(温馨提示:img_representation[0][‘embedding’])。

我的代码:

import main
import common
import numpy as np
import torch
import torch.nn.functional as F
import torch.nn as nn
from PIL import Image
from torchvision import transforms
import cv2
from model.DBFace import DBFace
from deepface import DeepFace
import ast
import mathtransform = transforms.Compose([transforms.ToTensor(),transforms.Resize((160, 160), antialias=True),
])
FEATURE_TXT_PATH = 'datas/feature.txt'
models = ["VGG-Face", "Facenet", "Facenet512", "OpenFace", "DeepFace", "DeepID", "ArcFace", "Dlib"]
# 候选区域
Center = [320,240]
x1 = 160
y1 = 80
x2 = 480
y2 = 400def preprocess_image(image_path):image = Image.open(image_path).convert('RGB')image = transform(image)return image.unsqueeze(0)class Face_recognition(nn.Module):def __init__(self):super().__init__()self.DeepFace = DeepFace.build_model(model_name="Facenet512")self.DBFace = DBFace().eval().cuda()self.DBFace.load("model/dbface.pth")try:self.features = self.txt_read()except:print('没有找到特征文件!')def verify_faces(self, img, log_features):for log_feature in log_features:img_representation = DeepFace.represent(img, "Facenet512", enforce_detection=False)target_face_feature = img_representation[0]['embedding']feature1 = np.array(target_face_feature)feature2 = np.array(log_feature)# 计算 L2 距离distance = np.linalg.norm(feature1 - feature2)# 计算余弦相似度# cosine_similarity = np.dot(target_face_feature, log_feature) / (np.linalg.norm(target_face_feature) * np.linalg.norm(log_feature))if distance < 0.4:return Trueelse:continuereturn Falsedef face_log(self, img):img_representation = DeepFace.represent(img, "Facenet512", enforce_detection=False)face_feature = img_representation[0]['embedding']with open(FEATURE_TXT_PATH, 'a') as file:file.write(str(face_feature) + '\n')print('注册完成!')def txt_read(self):all_feature = []with open(FEATURE_TXT_PATH, 'r') as file:features = file.readlines()for feature in features:all_feature.append(ast.literal_eval(feature))return all_featuredef face_detect_log(self):left = Trueright = Truecenter = Trueup = Truedown = Truecap = cv2.VideoCapture(0)cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)ok, frame = cap.read()img = frame.copy()while ok:objs = main.detect(self.DBFace, frame)for obj in objs:common.drawbbox(frame, obj)if len(objs) > 1:print("识别到多张人脸,仅支持单人脸识别认证!")cv2.putText(frame, 'Multiple faces detected, only single face recognition supported!', (x1-160, y1-40), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1, color=[0, 0, 255])else:for idx, land in enumerate(obj.landmark):x = int(land[0])y = int(land[1])cv2.putText(frame, f'{idx}', (x, y), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1, color=[0, 0, 255])# 后处理if self.set_head_in_rang(frame,obj):creen = self.creen_face(img, obj)if up:cv2.putText(frame,'Please up',(x1-80,y1-40), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1, color=[255, 0, 0])if self.turn_head_up(obj):self.face_log(creen)up = Falseif down and up == False:cv2.putText(frame, 'Please down', (x1-80,y1-40), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1, color=[255, 0, 0])if self.turn_head_down(obj):self.face_log(creen)down = Falseif left and up == False and down == False:cv2.putText(frame, 'Please left', (x1-80,y1-40), fontFace=cv2.FONT_HERSHEY_SIMPLEX,fontScale=1, color=[255, 0, 0])if self.turn_head_left(obj):self.face_log(creen)left = Falseif right and up == False and down == False and left == False:cv2.putText(frame, 'Please right', (x1-80,y1-40), fontFace=cv2.FONT_HERSHEY_SIMPLEX,fontScale=1, color=[255, 0, 0])if self.turn_head_right(obj):self.face_log(creen)right = Falseif center and up == False and down == False and left == False and right == False:cv2.putText(frame, 'Please place the face in the center', (x1-80,y1-40), fontFace=cv2.FONT_HERSHEY_SIMPLEX,fontScale=1, color=[255, 0, 0])if self.turn_head_center(obj):self.face_log(creen)center = Falseif up == False and down == False and left == False and right == False and center == False:cv2.putText(frame, 'Registration completed!', (x1-80,y1-40), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1,color=[0, 0, 255])return Truecv2.imshow("demo DBFace", frame)key = cv2.waitKey(1) & 0xFFif key == ord('q'):breakok, frame = cap.read()img = frame.copy()cap.release()cv2.destroyAllWindows()def set_head_in_rang(self,image,bbox):top_left = (x1, y1)bottom_right = (x2, y2)x, y, r, b = bbox.boxcv2.rectangle(image, top_left, bottom_right, color=(255, 0, 0), thickness=3)if y >= y1 and b <= y2 and x >= x1 and r <= x2:return Trueelse:cv2.putText(image,'Please place the face in the detection area.',(x1-160,y1-40), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1, color=[255, 0, 0])return Falsedef turn_head_up(self, obj):if math.fabs(obj.landmark[2][1] - obj.box[1]) / obj.height < 0.35:print('人脸已上转')return Trueelse:print('请向上转头')return Falsedef turn_head_down(self, obj):if math.fabs(obj.landmark[2][1] - obj.box[1]) / obj.height > 0.65:print('人脸已下转')return Trueelse:print('请向下转头')return Falsedef turn_head_left(self, obj):if math.fabs(obj.landmark[2][0] - obj.box[0]) / obj.width < 0.35:print('人脸已左转')return Trueelse:print('请向左转头')return Falsedef turn_head_right(self, obj):if math.fabs(obj.landmark[2][0] - obj.box[2]) / obj.width < 0.35:print('人脸已右转')return Trueelse:print('请向右转头')return Falsedef turn_head_center(self, obj):if math.sqrt(math.pow(obj.landmark[2][0] - obj.center[0],2) + math.pow(obj.landmark[2][1] - obj.center[1],2)) < 5:print('人脸已转正')return Trueelse:print('请转正人脸,并置于检测框中心')return Falsedef face_detect_check(self):config = Falsecap = cv2.VideoCapture('datas/test4.jpg') # 摄像头:0cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)ok, frame = cap.read()img = frame.copy()while ok:objs = main.detect(self.DBFace, frame)for obj in objs:common.drawbbox(frame, obj)if len(objs) > 1:print("识别到多张人脸,仅支持单人脸识别认证!")else:creen = self.creen_face(img, obj)for idx, land in enumerate(obj.landmark):x = int(land[0])y = int(land[1])cv2.putText(frame, f'{idx}', (x, y), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1,color=[0, 0, 255])if self.verify_faces(creen, self.features):config = Trueprint('人脸识别成功!!!')else:print('人脸识别失败!')cv2.imshow("demo DBFace", frame)key = cv2.waitKey(0) & 0xFFif key == ord('q') or config:breakok, frame = cap.read()img = frame.copy()cap.release()cv2.destroyAllWindows()def creen_face(self, img, obj):x, y, r, b = obj.boxcreen = img[int(y):int(b + 1),int(x):int(r + 1), :]cv2.imshow('creen',creen)# 计算两眼之间的斜率dx = obj.landmark[1][0] - obj.landmark[0][0]dy = obj.landmark[1][1] - obj.landmark[0][1]angle = np.degrees(np.arctan2(dy, dx))# 假设 image 是你要摆正的人脸图像aligned_face = align_face(creen, angle)cv2.imshow('aligned_face',aligned_face)return creendef align_face(image, angle):# 获取图像的尺寸(h, w) = image.shape[:2]# 创建旋转矩阵center = (w // 2, h // 2)M = cv2.getRotationMatrix2D(center, angle, 1.0)# 执行仿射变换aligned = cv2.warpAffine(image, M, (w, h),flags=cv2.INTER_CUBIC,borderMode=cv2.BORDER_CONSTANT,borderValue=(0, 0, 0))# 创建一个正方形底图region_mask = np.zeros((h, h, 3), dtype=np.uint8)# 计算region图片在底图上的起始位置start_x = (h - w) // 2start_y = (h - h) // 2# 使用NumPy索引将region图片放置到底图上region_mask[start_y:start_y + h, start_x:start_x + w, :] = alignedreturn region_maskdef onnx_dbface(output_path="dbface.onnx"):# 实例化DBFace模型并加载权重face_detector = DBFace().eval()face_detector.load("model/dbface.pth")# 设置模型输入的动态轴,这里我们假设输入图片大小为640x640dynamic_axes = {'input': {0: 'batch_size'}, 'output': {0: 'batch_size'}}# 设置一个随机的或真实的输入张量,用于导出模型dummy_input = torch.randn(1, 3, 640, 640)# 导出模型到ONNX格式torch.onnx.export(face_detector,dummy_input,output_path,verbose=False,opset_version=11,input_names=['input'],output_names=['output'],dynamic_axes=dynamic_axes)if __name__ == "__main__":Face = Face_recognition()if Face.face_detect_log():print('注册完毕!!!')# if Face.face_detect_check():#     print('人脸识别成功!!!')# img = cv2.imread('datas/test4.jpg')# if Face.verify_faces(img, Face.features):#     print('人脸认证通过')# else:#     print('人脸认证未通过')# onnx_dbface()

效果图

请添加图片描述
请添加图片描述
请添加图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com