使用 mtcnn 和 facenet 进行人脸识别

2023-12-05 19:20

本文主要是介绍使用 mtcnn 和 facenet 进行人脸识别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、前言

人脸识别目前有比较多的应用了,比如门禁系统,手机的人脸解锁等等,今天,我们也来实现一个简单的人脸识别。

二、思维导图

三、详细步骤

3.1 准备

3.1.1 facenet 权重文件下载

下载地址:https://drive.google.com/drive/folders/1pwQ3H4aJ8a6yyJHZkTwtjcL4wYWQb7bn,下载 facenet_keras_weights.h5权重文件到本地。

3.1.2 依赖库安装

pip 安装库的时候如果太慢,设置软件源的地址为清华源,设置命令:

pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
依赖库作用安装命令
OpenCV一个用于计算机视觉和图像处理的开源库。用于处理图像和视频。pip install opencv-python
mtcnn人脸检测的深度学习模型pip install mtcnn
tensorflow开源的机器学习框架pip install tensorflow
mysql-connector-python连接 mysql 数据库pip install mysql-connector-python
3.1.3 目录结构说明
├─docs 存放文档
├─encodings 存放本地图像特征值
├─facenet_model 存放 facenet 权重文件
├─font 存放简体字体
├─test_faces 测试集
├─train_faces 训练集
├─src 存放代码

3.2 训练人脸

3.2.1 人脸训练集准备

train_faces 文件夹下新建 hu_ge文件夹,然后从社交网络上获取胡歌图片放进去,作为训练集。

一张人脸生成的特征值显然是不够的,因此我们需要多张人脸,不考虑过拟合的情况下,人脸越多越精确。

3.2.2 加载模型

这边加载模型是 ResNetV2,没有引用库,而是手动去构建神经网络的,我尝试去直接使用 ResNet 库没成功,部分构建代码:

def inception_resnet_v2():inputs = Input(shape=(160, 160, 3))# 第一层是一个卷积层,应用了 32 个大小为 3x3 的滤波器x = Conv2D(32, 3, strides=2, padding='valid', use_bias=False, name= 'Conv2d_1a_3x3') (inputs)# 对输入进行批量归一化x = BatchNormalization(axis=3, momentum=0.995, epsilon=0.001, scale=False, name='Conv2d_1a_3x3_BatchNorm')(x)# 应用 ReLU 激活函数x = Activation('relu', name='Conv2d_1a_3x3_Activation')(x)x = Conv2D(32, 3, strides=1, padding='valid', use_bias=False, name= 'Conv2d_2a_3x3') (x)x = BatchNormalization(axis=3, momentum=0.995, epsilon=0.001, scale=False, name='Conv2d_2a_3x3_BatchNorm')(x)x = Activation('relu', name='Conv2d_2a_3x3_Activation')(x)x = Conv2D(64, 3, strides=1, padding='same', use_bias=False, name= 'Conv2d_2b_3x3') (x)x = BatchNormalization(axis=3, momentum=0.995, epsilon=0.001, scale=False, name='Conv2d_2b_3x3_BatchNorm')(x)x = Activation('relu', name='Conv2d_2b_3x3_Activation')(x)x = MaxPooling2D(3, strides=2, name='MaxPool_3a_3x3')(x)x = Conv2D(80, 1, strides=1, padding='valid', use_bias=False, name= 'Conv2d_3b_1x1') (x)x = BatchNormalization(axis=3, momentum=0.995, epsilon=0.001, scale=False, name='Conv2d_3b_1x1_BatchNorm')(x)x = Activation('relu', name='Conv2d_3b_1x1_Activation')(x)x = Conv2D(192, 3, strides=1, padding='valid', use_bias=False, name= 'Conv2d_4a_3x3') (x)x = BatchNormalization(axis=3, momentum=0.995, epsilon=0.001, scale=False, name='Conv2d_4a_3x3_BatchNorm')(x)x = Activation('relu', name='Conv2d_4a_3x3_Activation')(x)x = Conv2D(256, 3, strides=2, padding='valid', use_bias=False, name= 'Conv2d_4b_3x3') (x)x = BatchNormalization(axis=3, momentum=0.995, epsilon=0.001, scale=False, name='Conv2d_4b_3x3_BatchNorm')(x)x = Activation('relu', name='Conv2d_4b_3x3_Activation')(x)

这边就涉及到神经网络比较底层的知识,我也不太懂,我就直接使用了。
加载完模型后,加载 facenet 权重文件。
最后再加载 mtcnn 来识别人脸。

face_encoder = inception_resnet_v2()
facenet_weight_path = "../facenet_model/facenet_keras_weights.h5"
face_encoder.load_weights(facenet_weight_path)face_detector = mtcnn.MTCNN()
3.2.3 读取图片、转换颜色空间

OpenCV 读取图片默认是以 BGR 颜色空间,如果我们要给 mtcnn识别人脸,要先转为 RGB 颜色空间。

# 读取图片
img_BGR = cv2.imread(image_path)
# 将一幅图像从 BGR(蓝绿红)颜色空间转换为 RGB(红绿蓝)颜色空间
img_RGB = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2RGB)
3.2.4 mtcnn 识别人脸具体位置

MTCNN 是一种检测图像上的人脸和面部标志的神经网络。

x = face_detector.detect_faces(img_RGB)
print(x)

mtcnn 会生成人脸框的坐标和人脸上五个关键点的坐标,分别是左眼,右眼,鼻子,嘴唇的左边界,嘴唇的右边界。

{'box': [468, 98, 195, 249],'confidence': 0.9999933242797852,'keypoints': {'left_eye': (534, 190),'right_eye': (624, 186),'nose': (590, 236),'mouth_left': (549, 294),'mouth_right': (620, 291)}
}

显示一下:

# 人脸的框的左上角坐标和宽高
x1, y1, width, height = x[0]['box']
x1, y1 = abs(x1), abs(y1)
x2, y2 = x1 + width, y1 + height
# 绘制人脸框
cv2.rectangle(img_BGR, (x1, y1), (x2, y2), (0, 255, 0), 2)
# 绘制人脸关键点
for keypoint, coordinates in x[0]['keypoints'].items():cv2.circle(img_BGR, coordinates, 2, (0, 0, 255), -1)
# 显示
cv2.imshow('Detected Face', img_BGR)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 裁剪出人脸部分
face = img_RGB[y1:y2, x1:x2]
3.2.5 归一化、设置图片大小、生成图像特征值

归一化,将像素值从 [0, 255] 归一化到 [0, 1],如果训练的特征分布和测试的差异很大,那么对输入数据进行归一化,可以在训练和测试过程中保持一致的特征分布。

def normalize(img):"""归一化处理:将数据缩放到均值为 0,标准差为 1 的标准正态分布像素值通常是在 0 到 255 的范围内。例如,将像素值从 [0, 255] 归一化到 [0, 1]。:param img::return: 归一化结果"""# 获取所有像素的平均值,标准差mean, std = img.mean(), img.std()return (img - mean) / std

face_encoder.predict(face_d)[0]这个函数可以对输入的人脸图像进行特征提取,我们这边只获取单张人脸的特征,所以取下标 0。

face = normalize(face)# 重新设置大小
face = cv2.resize(face, required_shape)
# 扩展(增加)数组的维度
face_d = np.expand_dims(face, axis=0)
encode = face_encoder.predict(face_d)[0]
encodes.append(encode)

encode 只是一张图像的特征值,我们要训练很多张才能实现泛化效果比较好的模型,因此用 encodes 存放每一张图像的特征值。

3.2.6 特征求和、存放到数据库中
if encodes:# 特征求和# 计算每一列的总和encode = np.sum(encodes, axis=0)# 将特征向量标准化为单位向量encode = l2_normalizer.transform(np.expand_dims(encode, axis=0))[0]image_feature = base64.b64encode(encode).decode('utf-8')# 获取标签中文名 hu_ge -> 胡歌label_chinese_name = get_label_chinese_name(face_names)encoding_dict[face_names] = encodesave_image_feature(face_names, label_chinese_name, image_feature)

3.3 测试人脸

将需要测试的人脸图片放在 test_faces 文件夹下,这四张都是全新的图片,模型不知道的,这样才可以进行预测。

也是对每一张图像生成人脸的特征值,然后和数据库中的特征值进行比较。

dist = cosine(input_feature, image_feature)

**在机器学习中,欧氏距离用于特征空间中样本之间的相似性度量,通过 ****cosine**函数计算相似度,只要小于相似度阈值,我们就认为属于同一张人脸。

原来我是设置成 0.5,可能由于训练的样本数太少,不是冯提莫的图片也会被认为是冯提莫,造成错误识别,它的值是 0.480.49 这样,后面我改成 0.4 就好了。
冯提莫和胡歌的人脸特征我提前训练好了,因此这边可以识别到,杨幂和宋轶没有训练,所以识别不到,显示未知。

四、参考资料

  • facenet
  • mtcnn
  • Face Detection using MTCNN

这篇关于使用 mtcnn 和 facenet 进行人脸识别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/458809

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的