基于Python进行人脸验证人脸识别系统 毕业设计附完整代码 可直接运行

本文涉及的产品
视觉智能开放平台,视频资源包5000点
视觉智能开放平台,分割抠图1万点
视觉智能开放平台,图像资源包5000点
简介: 基于Python进行人脸验证人脸识别系统 毕业设计附完整代码 可直接运行

完整代码:


https://download.csdn.net/download/qq_38735017/87430696


通过下面项目的内容,将学到下面的东西: 1.实现人脸识别中的三元组损失函数 2.使用一个已经训练好的模型将人脸图像映射到 128-dimension encoding 3.使用这些 encoding 来执行人脸验证和人脸识别


人脸识别系统通常被分成两大类:


人脸验证:“这是不是本人”,需要通过刷身份证(或者能证明身份的有效证件)以及摄像头拍摄人脸照片,然后通过验证照片是否是你本人,比如车站人脸识别,手机人脸解锁功能,这些都是 1:1 的匹配问题。


人脸识别:“这个人是谁”,只需要通过摄像头去拍摄你的人脸,检测拍摄的人脸是否存在于系统中,比如公司的刷脸考勤,这样就不要去刷 ID 卡了,这是 1:K 的匹配问题


通过下面项目的内容,将学到下面的东西:


  • 实现人脸识别中的三元组损失函数
  • 使用一个已经训练好的模型将人脸图像映射到 128-dimension encoding
  • 使用这些 encoding 来执行人脸验证和人脸识别


(Note:在此次项目中,使用一个训练好的模型,该模型使用了 channels_first,这个变准现在 DL 社区还没有统一的标准(channels_first or channels_last))这样我们先导入包

acafdb0179452f925d60a8989105454f.png


我们能想到最简单的人脸验证,最简单的方法就是逐像素的比较两幅图像,选出图片之间误差小于阈值的,那么则可以判断是同一个人,可是,如果收到光照,明亮,人脸朝向,甚至是微小的差别,这样做的效果一定会很差,那么该怎么办呢??与使用原始图像之间的距离不同的是让系统学习构建一个 f(img),也就是构建一个 encoding,对该 encoding 的每个元素(这里比较 128)进行,可以更加准确的判断两幅图像是否属于同一个人


一、将人脸图像编码为 128 位的向量


1.1 使用卷积网络来进行编码


aceNet 模型需要大量的数据和长时间的训练,因为,在深度学习中,我们常见的操作是加载其他人已经训练过的权值,这里提供了模型的实现方法,可以查看 inception_blocks_v2.py 文件来查看是如何实现 faceRecoModel(input_shape)的。


①Inception 网络使用了 96 * 96 的 RGB 图像作为输入数据,图像数量为 m,输入的数据维度为(m,nc,nh,nw) = (m,3,96,96)


② 输出为(m,128)表示 encoding 后的 m 个 128 维的向量.


下面我们来创建一个人脸识别的模型

# 获取模型FRmodel=faceRecoModel(input_shape=(3,96,96))

FRmodel.count_params()###可以打印模型的总参数数量


836497d66bb422313177404ecff391e2.jpg



通过计算两个编码距离与阈值之间的误差,可以确定两幅图片是否是一个人

Encoding 是一个很好的方法:

  • 同一个人的两个图像的编码非常相似
  • 两个人不同的图像编码非常的不同


说了这么多,但是训练模型时拿什么损失函数呢,也就是什么样的损失函数能保证 encoding 是一个很好的方法呢?那就是三元损失函数


三元损失函数,会试图将同一个人的两个图像(A 和 P)的编码“拉近”,同时将两个不同的人的图像(A 和 N)的编码进一步“分离”,如下图(从左到右 Anchor, Positive, Negative):



82fae272ac89c62f0a96ac04ff7f547e.jpg



1.2 The Triplet Loss(三元组损失函数)


对于给定的图像 x,其编码为 f(x),其中 f 为神经网络的计算函数,如下。



f1e8d1388fd702f82d421a2c790e7667.jpg


我们使用三元组图像(A, P, N)进行训练:

  • A-是一个人的图像
  • P-是相对于“Anchor”的同一个人的另外一张图像
  • N-是相对于“Anchor”的不同的人的另外一张图像


所以我们希望编码 f(A)接近 f(P),即 ||f(A)f(P)||2 尽可能的小。而 $||f(A)f(N)||^2$ 尽可能


的大,我们还要保证图像 A 与图像 P 的差值至少比图像 N 的差值相差 α(这里 α=0.2)


$||f(A)f(P)||^2 +α≤||f(A)f(N)||^2$


$||f(A)f(P)||^2 +α-||f(A)f(N)||^2≤0$


这样就可以定义 Loss function 为:


$L(A,P,N) = max(||f(A) - f(P) ||^2 - ||f(A) - f(N)||^2+α, 0) $


那么,对于 m 组训练样本,cost function 为:


$J = \sum_{i=1}^{m}{L(A^{(i)},P^{(i)},N^{(i)})}$


那么我们来看一下代码实现:

ee03f056ea0d8d33985ef1f20ef171c2.png


二、加载模型


FaceNet 是通过最小化三元组损失来训练的,但是由于训练需要大量的数据和时间,所以我们不会从头训练,相反,加载一个已经训练好了的模型,运行下列代码来加载模型,可能会需要几分钟的时间。


1725c7e3de81de938a129f41f3f297ec.png



上面代码还计算了加载模型所需要的时间,另外我们来看一下三个人之间编码的距离的例子。


52a02972b343d29a6e239674d825be0b.jpg


这部分模型已经构建好,那么如何通过编码距离进行人脸验证和人脸识别呢??


三、模型应用


之前对“欢乐家”添加了笑脸识别,现在要构建一个人脸验证系统,以便只允许来自指定列表的人员进入。为了通过门禁,每个人都必须在门口刷身份证以表明自己的身份,然后人脸识别系统将检查他们到底是谁。


3.1 人脸验证


对于人脸验证系统,首先需要构建一个数据库,里面包含了允许进入的人员的编码向量,我们使用 fr_uitls.img_to_encoding(image_path, model)函数来生成编码,它会根据图像来进行模型的前向传播计算人脸图像编码。


我们这里的数据库使用的是一个字典来表示,这个字典将每个人的名字映射到他们面部的 128 维编码上,如下(Note:这里要把 images 目录保存在当前目录下面,否则会报错)。


"""构建一个数据库,里面包含了允许进入的人员的编码向量,注意这里要把 images 目录保存在当前目录下面,否则会报错,至于为什么我也没搞清楚""" database={}database["danielle"]=img_to_encoding("images\\danielle.png",FRmodel)database["younes"]=img_to_encoding("images\\younes.jpg",FRmodel)database["tian"]=img_to_encoding("images\\tian.jpg",FRmodel)database["andrew"]=img_to_encoding("images\\andrew.jpg",FRmodel)database["kian"]=img_to_encoding("images\\kian.jpg",FRmodel)database["dan"]=img_to_encoding("images\\dan.jpg",FRmodel)database["sebastiano"]=img_to_encoding("images\\sebastiano.jpg",FRmodel)database["bertrand"]=img_to_encoding("images\\bertrand.jpg",FRmodel)database["kevin"]=img_to_encoding("images\\kevin.jpg",FRmodel)database["felix"]=img_to_encoding("images\\felix.jpg",FRmodel)database["benoit"]=img_to_encoding("images\\benoit.jpg",FRmodel)database["arnaud"]=img_to_encoding("images\\arnaud.jpg",FRmodel)


人脸验证的思想很简单,即当有人出现在的门前刷他们的身份证的时候,你可以在数据库中根据身份证上的名字查找他们的对应的编码,用它来检查站在门前的人是否与身份证上的名字匹配,代码如下。


6dc49277130de626f3d3a074166f4626.png

ebe9c364a94e5ac606319a0b07add696.png


我们来测试一下,现在 younes 在门外,相机已经拍下了照片并存放在了

(“images/camera_0.jpg”),现在我们来验证一下他是否能开门成功。


3693925af422514f0dd6aec62e736d53.jpg

# younes 来到门前,摄像头拍摄的照片存入 camera_0.jpg,刷 ID 验证是否是 younes 本人
dist, door_open = verify("images\\camera_0.jpg", "younes", database, FRmodel)
print(dist, door_open)

It's younes,welcome home!


0.6710074 True


还有一种情况,比如 Benoit 已经被禁止进入,也从数据库中删除了 Benoit 的信息,但是他偷了 Kian 的身份证并试图通过门禁,我们来看看他能不能进入呢?(“images/camera_2.jpg”)


a22d2f2b0454eb2fd2be044e634888a8.jpg

# Benoit 拿着 kian 的 ID 来,刷 kian 的 ID 卡想进入房子,结果应该是验证失败
dist1, door_open1 = verify("images\\camera_2.jpg", "kian", database, FRmodel)
print(dist1, door_open1)

It,s notkian,please go away

0.85800153 False


3.2 人脸识别


对于人脸验证系统有个弊端,那就是如果一个人的身份证不见了,那么他将无法进入房子,要是不用身份证那个多好啊,当然这是可以实现的,也就是这里所说的人脸识别系统,这样就不用再带身份证了,一个被授权的人只要走到房子前面,前门就会自动为他们打开! 代码思路和实现如下:


cd9f9cc83fff65491a7223f2d411770e.png


我们也来看一下效果怎么样, younes 和 bertrand 站在前门,相机给他拍了张照片(“images/camera_0.jpg”)和(“images/camera_1.jpg”)。让我们看看 who_it_is()算法是否识别 younes 和 bertrand


28e1915df33cb9f4ed8bfd2db08a7823.jpg


2bca1847ed31ff2ca4c6e74c0340e31c.jpg

min_dist,identity=who_is_it("images\\camera_0.jpg",database,FRmodel)print(min_dist,identity)min_dist1,identity1=who_is_it("images\\camera_1.jpg",database,FRmodel)print(min_dist1,

it's younes, the distance is 0.6710074

0.6710074 younes

it's bertrand, the distance is 0.46740144

0.46740144 bertran


四、总结


  • 人脸验证解决了更容易的 1:1 匹配问题,人脸识别解决了更难的 1∶k 匹配问题。
  • Triplet loss 是训练神经网络学习人脸图像编码的一种有效的损失函数。
  • 相同的编码可用于验证和识别。测量两个图像编码之间的距离可以确定它们是否是同一个人的图片。
相关文章
|
18天前
|
开发框架 数据建模 中间件
Python中的装饰器:简化代码,增强功能
在Python的世界里,装饰器是那些静悄悄的幕后英雄。它们不张扬,却能默默地为函数或类增添强大的功能。本文将带你了解装饰器的魅力所在,从基础概念到实际应用,我们一步步揭开装饰器的神秘面纱。准备好了吗?让我们开始这段简洁而富有启发性的旅程吧!
26 6
|
11天前
|
数据可视化 Python
以下是一些常用的图表类型及其Python代码示例,使用Matplotlib和Seaborn库。
通过这些思维导图和分析说明表,您可以更直观地理解和选择适合的数据可视化图表类型,帮助更有效地展示和分析数据。
52 8
|
18天前
|
API Python
【Azure Developer】分享一段Python代码调用Graph API创建用户的示例
分享一段Python代码调用Graph API创建用户的示例
41 11
|
20天前
|
测试技术 Python
探索Python中的装饰器:简化代码,增强功能
在Python的世界中,装饰器是那些能够为我们的代码增添魔力的小精灵。它们不仅让代码看起来更加优雅,还能在不改变原有函数定义的情况下,增加额外的功能。本文将通过生动的例子和易于理解的语言,带你领略装饰器的奥秘,从基础概念到实际应用,一起开启Python装饰器的奇妙旅程。
34 11
|
16天前
|
Python
探索Python中的装饰器:简化代码,增强功能
在Python的世界里,装饰器就像是给函数穿上了一件神奇的外套,让它们拥有了超能力。本文将通过浅显易懂的语言和生动的比喻,带你了解装饰器的基本概念、使用方法以及它们如何让你的代码变得更加简洁高效。让我们一起揭开装饰器的神秘面纱,看看它是如何在不改变函数核心逻辑的情况下,为函数增添新功能的吧!
|
16天前
|
程序员 测试技术 数据安全/隐私保护
深入理解Python装饰器:提升代码重用与可读性
本文旨在为中高级Python开发者提供一份关于装饰器的深度解析。通过探讨装饰器的基本原理、类型以及在实际项目中的应用案例,帮助读者更好地理解并运用这一强大的语言特性。不同于常规摘要,本文将以一个实际的软件开发场景引入,逐步揭示装饰器如何优化代码结构,提高开发效率和代码质量。
42 6
|
21天前
|
Python
如何提高Python代码的可读性?
如何提高Python代码的可读性?
34 4
|
21天前
|
Python
Python编程入门:从零开始的代码旅程
本文是一篇针对Python编程初学者的入门指南,将介绍Python的基本语法、数据类型、控制结构以及函数等概念。文章旨在帮助读者快速掌握Python编程的基础知识,并能够编写简单的Python程序。通过本文的学习,读者将能够理解Python代码的基本结构和逻辑,为进一步深入学习打下坚实的基础。
|
25天前
|
设计模式 监控 程序员
Python中的装饰器:功能增强与代码复用的利器####
本文深入探讨了Python中装饰器的工作原理、应用场景及其在提升代码可读性、减少重复劳动方面的优势。不同于传统方法的冗长和复杂,装饰器提供了一种优雅且高效的方式来增强函数或方法的功能。通过具体实例,我们将揭示装饰器如何简化错误处理、日志记录及性能监控等常见任务,使开发者能够专注于核心业务逻辑的实现。 ####
|
23天前
|
存储 设计模式 缓存
Python中的装饰器:代码的魔法增强剂####
本文将深入探讨Python语言中一个强大而灵活的特性——装饰器。不同于传统的函数调用,装饰器提供了一种优雅的方式来扩展或修改函数行为,无需直接修改原函数代码。我们将通过实例分析,揭示装饰器的定义、工作原理及其在实际项目中的应用价值,旨在帮助开发者更好地理解和利用这一高级功能,提升代码的可读性与维护性。 ####

热门文章

最新文章

下一篇
DataWorks