Python实现人脸识别功能

Python实现人脸识别功能

闲来没事,记录一下前几天学习的人脸识别小项目。

要想实现人脸识别,我们首先要搞明白,人脸识别主要分为哪些步骤?为了提高人脸识别的准确性,我们首先要把图像或视频中的人脸检测出来,然后使用分类网络,对检测到的人脸进行分类。

概括起来,主要包括:人脸检测人脸分类两个部分。

人脸检测

人脸检测部分我们直接使用现成的 MTCNN,它的模型结构如下图所示,主要由三个级联的简单网络组成。

首先将图像重新缩放为不同尺度的图像,然后第一个网络负责提出候选框,第二个网络对候选框进行过滤,留下更加精准的候选框,第三个网络进一步回归和过滤,输出预测的面部边界框和特征点位置。

在这里插入图片描述

下图是该网络的模型结构参数,可以发现该网络结构由简单的若干个卷积层组成,结构简单,运行十分快速,因此适用于在线的人脸识别。

在这里插入图片描述
这里代码也很简单,有现成的:

import cv2
from mtcnn_cv2 import MTCNN# 加载模型(MTCNN)
mtcnn = MTCNN()# 打开摄像头
cap = cv2.VideoCapture(0)while True:# 读取一帧图像ret, img = cap.read()# 如果读取成功if ret:# 将图像转为RGB格式img_rgb = cv2.cvtColor(src=img, code=cv2.COLOR_BGR2RGB)# 人脸检测(检测图像中是否存在人脸)faces = mtcnn.detect_faces(img=img_rgb)

人脸识别

在人脸识别部分,我们首先将想要识别的人脸图片存入文件夹,然后计算视频中检测到的人脸与文件夹内人脸的差异,根据阈值判断检测到的人脸是已知的,还是陌生人。

import cv2
from mtcnn_cv2 import MTCNN
from img_mark import mark_face
from img_mark import rec_face# 加载模型(MTCNN)
mtcnn = MTCNN()# 打开摄像头
cap = cv2.VideoCapture(0)while True:# 读取一帧图像ret, img = cap.read()# 如果读取成功if ret:# 将图像转为RGB格式img_rgb = cv2.cvtColor(src=img, code=cv2.COLOR_BGR2RGB)# 人脸检测(检测图像中是否存在人脸)faces = mtcnn.detect_faces(img=img_rgb)if faces:# 人脸标注(box, landmark)mark_face(img=img, faces=faces)# 人脸识别(识别身份)rec_face(img=img, faces=faces)# 显示图像cv2.imshow(winname="love", mat=img)cv2.waitKey(delay=1)else:# 读取失败,退出循环break# 释放资源
cap.release()
cv2.destroyAllWindows()

还有一个 img_mark.py 文件定义了人脸识别的功能部分。

from torchvision import transforms
from PIL import Image
import numpy as np
import os
import cv2
from res_facenet.models import model_921# 加载模型(FaceNet)
model921 = model_921()def reg_faces(root="../faces"):"""使用 FaceNet 录入人脸:param root: 存储的人脸仓库:return:"""# 定义空字典,存放录入的人脸faces = {}# 预处理preprocess = [transforms.Resize(224),transforms.CenterCrop(224),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225])]trans = transforms.Compose(preprocess)# 读取带录入的人脸for file in os.listdir(root):if file.endswith(".jpg"):# 拼接完整路径file_path = os.path.join(root, file)# 读取图像内容并预处理img = trans(Image.open(file_path)).unsqueeze(0)# 使用FaceNet模型,将人脸变成128维向量embed = model921(img)# 将录入的脸存储在字典中faces[file.split(".")[0]] = embed.detach().numpy()[0]return facesdef embed_faces(img=None):"""将人脸图像变成一个向量"""preprocess = [transforms.Resize(224),transforms.CenterCrop(224),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225])]trans = transforms.Compose(preprocess)img = trans(Image.fromarray(obj=img)).unsqueeze(0)embed = model921(img).detach().numpy()[0]return embeddef get_dist(face, faces):"""求解欧氏距离:param face: 预测的结果:param faces: 库中的结果:return:"""result = []for n, f in faces.items():result.append((n, np.sqrt(((f - face) ** 2).sum())))result.sort(key=lambda ele: ele[1])return result# 获取人脸库
face_db = reg_faces()def mark_face(img=None, faces=None):for face in faces:x, y, w, h = face["box"]confidence = face["confidence"]keypoints = face["keypoints"]if confidence > 0.9:cv2.rectangle(img=img, pt1=(x, y), pt2=((x+w), (y+h)), color=(0, 0, 200))# 左眼cv2.circle(img=img, center=keypoints["left_eye"], radius=2, color=(200, 0, 0))# 右眼cv2.circle(img=img, center=keypoints["right_eye"], radius=2, color=(200, 0, 0))# 鼻子cv2.circle(img=img, center=keypoints["nose"], radius=2, color=(200, 0, 0))# 左嘴角cv2.circle(img=img, center=keypoints["mouth_left"], radius=2, color=(200, 0, 0))# 右嘴角cv2.circle(img=img, center=keypoints["mouth_right"], radius=2, color=(200, 0, 0))def rec_face(img, faces):"""人脸识别:param img::param faces::return:"""# 将图像转为RGB格式img_rgb = cv2.cvtColor(src=img, code=cv2.COLOR_BGR2RGB)for face in faces:x, y, w, h = face["box"]confidence = face["confidence"]# 通过置信度,过滤部分人脸if confidence > 0.9:# 截取人脸data = img_rgb[y:y+h, x:x+w, :]# 嵌入向量vec = embed_faces(img=data)# 计算距离result = get_dist(vec, face_db)# 求最短距离name, distance = result[0]print(distance)# 超过距离的阈值,则认为是陌生人if distance > 1.5:name = "Stranger"# 将名字打印到图像中cv2.putText(img=img, text=name, org=(x, y+h+30), color=(0, 200, 0),fontFace=cv2.FONT_HERSHEY_SIMPLEX,fontScale=1)

放张简单的效果图。

在这里插入图片描述

完整的代码文件见百度网盘:链接:https://pan.baidu.com/s/15q69SjVFEhfJ9WpgWSyhbg
提取码:pymx

日常学习记录,一起交流讨论吧!侵权联系~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/8757.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于DNN深度学习网络的OFDM+QPSK信号检测算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ............................................................................. Transmitt…

XGBoost实例——皮马印第安人糖尿病预测和特征筛选

利用皮马印第安人糖尿病数据集来预测皮马印第安人的糖尿病,以下是数据集的信息: Pregnancies:怀孕次数Glucose:葡萄糖BloodPressure:血压 (mm Hg)SkinThickness:皮层厚度 (mm)Insulin:胰岛素 2…

区块链学习笔记

区块链技术与应用 数组 列表 二叉树 哈希函数 BTC中的密码学原理 cryptographic hash function collsion resistance(碰撞抵抗) 碰撞指的是找到两个不同的输入值,使得它们的哈希值相同。也就是说,如果存在任意两个输入x和y,满足x ≠ y…

【ES】---ES的聚合(aggregations)

目录 一、前言1、聚合分类2、聚合的实现方式二、RestAPI--bucket聚合案例11、按照类型分bucket2、按照(String)时间分bucket三、RestAPI-- metric聚合案例11、metric指标统计四、RestAPI-- pipeline聚合案例1一、前言 聚合是对文档数据的统计、分析、计算。 注意:参与聚合的字…

YOLOX-PAI 论文学习

1. 解决了什么问题? 对 YOLOX 做加速,在单张 Tesla V100 上取得了 42.8 42.8 42.8mAP,推理速度为 1 毫秒。 2. 提出了什么方法? 2.1 主干网络 YOLOv6 和 PP-YOLOE 都将主干网络从 CSPNet 切换到了 RepVGG。RepVGG 在推理时&a…

MyBatis学习笔记之高级映射及延迟加载

文章目录 环境搭建,数据配置多对一的映射的思路逻辑级联属性映射association分布查询 一对多的映射的思路逻辑collection分布 环境搭建,数据配置 t_class表 t_stu表 多对一的映射的思路逻辑 多对一:多个学生对应一个班级 多的一方是st…

mac系统占用100多G怎么清除 mac内存系统占用了好多怎么清理

mac电脑运行速度足以傲视其他电脑系统,不易卡顿死机是苹果电脑的优势,但是其偏小的存储空间令人十分头痛。如果你的mac磁盘容量是仅有12GB,在使用一段时间之后,系统内存很有可能就要占用100多G,很快电脑会出现空间不够…

Android12之快速查找静态注册jni函数方法(一百六十一)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…

【C语言15】单链表,(对于二级指针与一级指针应用的详细讲述)

文章目录 单链表1.单链表的介绍2.单链表的实现2.1.1单链表结点的创建与销毁2.1.2单链表尾插2.1.3单链表打印2.1.4尾删2.1.5头插2.1.6头删2.1.7查找2.1.8在pos位置之后插入数据2.1.9删除pos位置 单链表 1.单链表的介绍 链表是一种物理存储结构上非连续、非顺序的存储结构&#…

Vue 本地应用 图片切换 v-show v-bind实践

点击切换图片的本质,其实修改的是img标签的src属性。 图片的地址有很多个,在js当中通过数组来保存多个数据,数组的取值结合索引,根据索引可以来判断是否是第一张还是最后一张。 图片的变化本质是src属性被修改了,属性…

国标GB28181视频监控平台EasyGBS视频无法播放,抓包返回ICMP是什么原因?

国标GB28181视频平台EasyGBS是基于国标GB/T28181协议的行业内安防视频流媒体能力平台,可实现的视频功能包括:实时监控直播、录像、检索与回看、语音对讲、云存储、告警、平台级联等功能。国标GB28181视频监控平台部署简单、可拓展性强,支持将…

微服务——统一网关Getway

为什么需要网关? 网关的两种实现: 网关Getway——快速入门 步骤一 网关背身也是一个微服务,需要注册到nacos中去 步骤二 成功运行后 可以通过网关进行请求转发到对应服务。 流程如下: 路由断言工厂 网关路由可以配置的东西有如下。 spri…

【深度学习】yolov 图片训练的时候的遇到的warning: corrupt JPEG restored and saved

报错原因 是图片在dataset.py 走验证时报的错误。 if im.format.lower() in (jpg, jpeg):with open(im_file, rb) as f:f.seek(-2, 2)if f.read() ! b\xff\xd9: # corrupt JPEGImageOps.exif_transpose(Image.open(im_file)).save(im_file, JPEG, subsampling0, quality100)m…

Redis 九种数据类型的基本操作

一、redis9种数据类型的基本操作 ①key操作 #查找所有的key 127.0.0.1:6379> keys * 1) "pop" 2) "mylist" 3) "lpl" 4) "myset" #设置key的过期时间 返回1表示执行成功,0表示失败,出现问题 127.0.0.1:6379…

Qt Creator mainwindow.obj:-1: error: LNK2019

构建的时候报错: mainwindow.obj:-1: error: LNK2019: 无法解析的外部符号 "public: __thiscall mynotedig::mynotedig(class QWidget *)" (??0mynotedigQAEPAVQWidgetZ),该符号在函数 "public: void __thiscall MainWindow::mynoteab…

VMPWN的入门级别题目详解(一)

实验一 VMPWN1 题目简介 这是一道基础的VM相关题目,VMPWN的入门级别题目。前面提到VMPWN一般都是接收字节码然后对字节码进行解析,但是这道题目不接受字节码,它接收字节码的更高一级语言:汇编。程序直接接收类似”mov”、”add”…

Dockerfile 创建镜像,构建LNMP+wordpress架构

目录 一、Dockerfile 构建镜像 1.Dockerfile 构建 nginx镜像 1.1创建 nginx Dockerfile 目录 1.2编写 Dockerfile 文件 1.3构建nginx镜像 2.Dockerfile 构建 mysql 镜像 2.1创建 mysql Dockerfile 目录 2.2修改mysql配置文件 2.3编写 Dockerfile 文件 2.4构建mysql镜…

Cesium态势标绘专题-圆角矩形(标绘+编辑)

标绘专题介绍:态势标绘专题介绍_总要学点什么的博客-CSDN博客 入口文件:Cesium态势标绘专题-入口_总要学点什么的博客-CSDN博客 辅助文件:Cesium态势标绘专题-辅助文件_总要学点什么的博客-CSDN博客 本专题没有废话,只有代码,代码中涉及到的引入文件方法,从上面三个链…

[RabbitMQ] RabbitMQ简单概述,用法和交换机模型

MQ概述: Message Queue(消息队列),实在消息的传输过程中保存消息的容器,都用于分布式系统之间进行通信 分布式系统通信的两种方式:直接远程调用 和 借助第三昂 完成间接通信 发送方称谓生产者,接收方称为消费者 MQ优…

JMeter基础入门教程之CSV数据文件设置CSV Data Set Config

最近在做压力测试,登录功能用到了配置元件:CSV 数据文件设置,可以将登录用户名和密码放在一个csv文件中,然后通过CSV数据文件设置元件读取出来,用来做压测。 一、CSV文件 CSV文件小知识分享:是指"逗号…