OpenCV 人脸识别 源代码
请直接查看原文 OpenCV 人脸识别 源代码 https://hotdog29.com/?p=553
在 2019年7月6日 上张贴 由 hotdog发表回复
opencv 人脸识别
您当然可以换成自己的面部数据集!您需要做的就是按照我的目录结构插入您自己的面部
OpenCV人脸识别
在今天的教程中,您将学习如何使用OpenCV库执行面部识别。
您可能想知道本教程与我几个月前用dlib进行人脸识别时所写的教程有何不同?
dlib(显然)
face_recognition(这是一组易于使用的面部识别实用程序,包含dlib)
虽然我们使用OpenCV来促进面部识别,但OpenCV 本身并不负责识别面部。
在今天的教程中,我们将学习如何将深度学习和OpenCV一起应用(除了 scikit-learn 之外没有其他库):
检测面部
计算128-d面部嵌入以量化面部
在嵌入之上训练支持向量机(SVM)
识别图像和视频流中的面部
所有这些任务都将通过OpenCV完成,使我们能够获得“纯粹的” OpenCV 人脸识别管道。
图1: OpenCV人脸识别管道概述。关键步骤是CNN特征提取器,可生成128维面部嵌入。(来源)
为了构建我们的OpenCV人脸识别管道,我们将在两个关键步骤中应用深度学习:
查看整个FaceNet实现超出了本教程的范围,但管道的要点可以在上面的图1中看到。
首先,我们将图像或视频帧输入到人脸识别管道。给定输入图像,我们应用面部检测来检测图像中面部的位置。
顾名思义,面部对齐是(1)识别面部的几何结构和(2)基于平移,旋转和缩放来尝试获得面部的规范对齐的过程。
虽然可选,但已经证明面部对齐可以提高某些管道中的面部识别精度。
在我们(可选)应用面对齐和裁剪之后,我们通过深度神经网络传递输入面:
FaceNet深度学习模型计算128-d嵌入,量化面部本身。
输入数据到网络
三重损失功能
为了训练具有深度学习的人脸识别模型,每个输入批量数据包括三个图像:
1, The anchor( 锚 )
2, The positive image
3, The negative image
另一方面,负面图像不具有相同的身份,可能属于人B,C甚至Y!
关键是锚和正图像都属于同一个人/面部,而负面图像不包含相同的面部。
神经网络计算每个面的128-d嵌入,然后调整网络的权重(通过三元组丢失函数),这样:
锚和正像的128-d嵌入更靠近在一起
与此同时,推动负面图像父亲的嵌入
以这种方式,网络能够学习量化面部并返回适合于面部识别的高度鲁棒且有区别的嵌入。
进而,我们实际上可以重用为我们自己的应用程序OpenFace模型,而无需显式地训练它!
如果您有兴趣了解有关三联体丢失的详细信息以及如何使用它来训练面部嵌入模型,请务必参考我之前的博客文章 以及Schroff等人。出版。
如果您正在构建自己的人脸识别数据集,理想情况下,我建议每个人想要识别10-20张图像 – 请务必参考“缺点,限制以及如何获得更高的人脸识别准确度”部分博客文章了解更多详情。
步骤#1:从面部数据集中提取嵌入
现在我们了解了人脸识别的工作原理并审查了我们的项目结构,让我们开始构建我们的OpenCV人脸识别管道。
我们在第2-8行导入我们所需的包 。您需要 安装OpenCV和 imutils。要安装OpenCV。可以参考我的教程 pip 安装 opencv 我的imutils软件包可以用pip安装
1 $ pip install --upgrade imutils
接下来,我们处理命令行参数:
基于第37行构建的 imagePaths列表 包含数据集中每个图像的路径。我已经通过 imutils function, paths.list_images 简化了
我们的嵌入和相应的名称将保存在两个列表中: knownEmbeddings 和 knownNames (第41和42行)。
我们还将通过名为total的变量 (第45行)跟踪我们处理的面数 。
让我们开始在图像路径上循环 – 这个循环将负责从每个图像中找到的面中提取嵌入
首先,我们 从路径中提取人的 名字(第52行)。要解释这是如何工作的,请在我的Python shell中运行以下示例
最后,我们通过加载图像 并将其调整为已知宽度(第57和58行)来 包装上面的代码块。
在 62-64行,我们构造了一个blob。要了解有关此过程的更多信息,请阅读 深度学习:OpenCV的blobFromImage如何工作。
从那里我们通过将imageBlob 传递到探测器网络来 检测图像中的 面部(第68和69行)。
假设我们至少有一个检测,我们将进入if语句的主体(第72行)。
我们假设图像中只有一个面,因此我们以最高置信度提取检测 并检查以确保置信度满足用于滤除弱检测的最小概率阈值(第75-81行)。
假设我们已达到该阈值,我们提取 面部 ROI并抓取/检查尺寸以确保面部 ROI足够大(第84-93行)。
我们构建另一个blob,这次是从第98行和第99行的面部ROI(不是我们之前做过的整个图像) 。
随后,我们将faceBlob传递给 嵌入器CNN(第100和101行)。这将生成 描述面部的128-D向量( vec)。我们将利用这些数据通过机器学习识别新面孔。
然后我们分别添加 名称 并将vec嵌入 到 knownNames 和 knownEmbeddings (第105和106行)。
我们也不能忘记我们设置的跟踪总 面数的变量 – 我们继续并在第107行增加值 。
我们继续这个循环图像,检测面部,并为我们的数据集中的每个图像提取面部嵌入的过程 。
我们将名称和嵌入数据添加到字典中,然后 在第110-114行的pickle文件中序列化 数据。
从那里,打开一个终端并执行以下命令来计算OpenCV的面嵌入
在这里你可以看到我们已经提取了18个面嵌入,每个图像一个(每个类6个)在我们的输入面数据集中。
在我之前的人脸识别教程中, 我们发现了k-NN的修改版本如何用于通过dlib和face_recognition库创建的128-d嵌入的人脸识别。
今天,我想分享一下我们如何在嵌入之上构建一个更强大的分类器 – 如果您愿意,您也可以在基于dlib的人脸识别管道中使用相同的方法。
在运行此脚本之前,我们需要在我们的环境中安装scikit-learn,一个机器学习库。你可以通过pip安装它
1 $ pip install scikit-learn
我们在第2-5行导入我们的包和模块 。我们将使用scikit-learn的支持向量机(SVM)实现,这是一种常见的机器学习模型。
在这里,我们从载入我们的嵌入 从步骤#1的 第19行。我们不会在此模型训练脚本中生成任何嵌入 – 我们将使用先前生成和序列化的嵌入。
然后我们初始化我们的scikit-learn LabelEncoder 并编码我们的名称 标签 (第23和24行)。
在 第29行,我们初始化我们的SVM模型,在 第30行,我们 拟合 模型(也称为“训练模型”)。
在这里,我们使用线性支持向量机(SVM),但如果您愿意,可以尝试使用其他机器学习模型。
训练模型后,我们将模型和标签编码器输出到磁盘作为pickle文件。
我们在这个块中将两个pickle文件写入磁盘 – 面部识别器模型和标签编码器
现在我们已经完成了train_model .py的编码 ,让我们将它应用于我们提取的面嵌入
在这里,您可以看到我们的SVM已经通过嵌入式培训,并且(1)SVM本身和(2)标签编码已写入磁盘,使我们能够将它们应用于输入图像和视频。
第3步:使用OpenCV识别人脸
我们现在准备用OpenCV进行人脸识别!
我们将首先识别本节中图像中的面部,然后继续在下一节中识别视频流中的面部。
我们 在第2-7行导入我们所需的包 。此时,您应该安装每个软件包。
现在我们已经处理了导入和命令行参数,让我们将三个模型从磁盘加载到内存中
我们在这个块中加载了三个模型。存在冗余的风险,我想明确提醒您模型之间的差异:
我们还加载了标签编码器,其中包含我们模型可识别的人员的姓名(第38行)。
首先,我们构造一个faceBlob (来自 面部 ROI)并将其传递 给 嵌入器 以生成描述面部的128-D向量(第80-83行)
然后,我们 通过我们的SVM识别器模型(第86行)传递 vec,其结果是我们对面对ROI的人的预测 。
我们采用最高概率指数(第87行)并查询我们的标签编码器以找到 名称 (第89行)。在两者之间,我在第88行提取概率 。
注意: 您可以通过对概率应用额外的阈值测试来进一步滤除弱脸识别。例如,如果proba < T (其中 T 是您定义的变量),则插入 可以提供额外的过滤层,以确保较少的假阳性面部识别。
我们 在第93行构造一个 包含名称和概率的 文本字符串 。
然后我们在脸部周围画一个矩形并将文本放在盒子上方(第94-98行)。
然后我们最终在屏幕上显示结果,直到按下一个键(第101和102行)。
要将我们的OpenCV面部识别管道应用于我提供的图像(或您自己的数据集+测试图像),请确保使用博客文章的“下载”部分下载代码,训练模型和示例图像。
图4: OpenCV的人脸识别已经认识到我在侏罗纪世界:堕落王国电影放映。
我的面部预测只有47.15%的信心; 但是,这种信心高于 “未知”类。
图5:我的妻子Trisha和我在OpenCV +深度学习面部识别的飞机上拍照。
在最后一个例子中,让我们看看当我们的模型无法识别实际面部时会发生什么
第三张图片是一个“未知”人物的例子,实际上是来自American Psycho的 Patrick Bateman – 相信我,这不是一个你想要看到的人出现在你的图像或视频流中!
识别视频流中的面孔
作为奖励,我决定在视频流中加入专门用于OpenCV人脸识别的部分!
实际的管道本身几乎与识别图像中的面部相同,只有一些更新,我们将在此过程中进行检查。
开拓 recognize_video .py 文件,让我们开始吧
我们的导入与 上面的步骤#3部分相同 ,除了 我们使用 imutils的第2行和第3 行。视频 模块。我们将使用 VideoStream 从我们的相机和FPS捕获帧 以计算每秒帧数统计数据。
除了我们没有通过命令行将路径传递给静态图像之外,命令行参数也是相同的。相反,我们将获取对我们网络摄像头的引用,然后处理视频。如果需要查看参数,请参阅 步骤3。
在这里我们加载面部 检测器 ,面部 嵌入器 模型,面部 识别器 模型(线性SVM)和标签编码器。
如果您对三种型号或标签编码器感到困惑,请务必参考 步骤#3。
我们的 VideoStream 对象已初始化并在第43行启动 。我们等待相机传感器在44号线上预热 。
我们还初始化每秒帧数(第47行)并开始在第50行的帧上循环 。我们 从第52行的网络摄像头 抓取一个 框架。
从这里开始,一切都与第3步相同。我们 调整 帧的大小(L ine 57),然后我们从帧构造一个blob +检测面的位置(第61-68行)。
正如在上一节中一样,我们开始循环 检测 并滤除弱检测(第71-77行)。然后我们提取 面部 ROI以及确保空间尺寸足够大以用于后续步骤(第84-89行)。
正如你所看到的,Trisha和我的脸都被正确识别了!我们的OpenCV人脸识别管道也在我的iMac上获得了~16 FPS。在我的MacBook Pro上,我获得了大约14 FPS的吞吐率。
图8:所有人脸识别系统都容易出错。永远不会有100%准确的人脸识别系统。
您如何提高您的OpenCV人脸识别准确度?在本节中,我将详细介绍一些建议的方法,以提高人脸识别管道的准确性
图9:大多数人没有用足够的数据训练他们的OpenCV人脸识别模型。(图片来源)
在我之前的人脸识别教程中,少数PyImageSearch读者询问为什么他们的面部识别准确度很低而且面孔被错误分类
我得到的印象是大多数读者已经知道他们需要更多的面部图像,因为他们每个人只有一个或两个示例面孔,但我怀疑他们希望我从我的一些提示和技巧中解决计算机视觉技术问题。
如果你发现自己的人脸识别准确率低,并且每个人只有一些示例面孔,那么收集更多数据 – 没有“计算机视觉技巧”可以帮助你避免数据收集过程。
加大您的数据,您将拥有更好的OpenCV人脸识别渠道。 一般来说,我建议每人至少10-20张面孔。
图9:为OpenCV进行面部对齐面部识别可以显着提高面部识别性能。
人脸识别模型OpenCV用于计算来自OpenFace项目的128-d面嵌入。
识别图像中面部的几何结构。
尝试基于平移,旋转和缩放获得面部的规范对齐。
从 本节顶部的图9中可以看出,我有:
查看我的博客文章, 使用OpenCV和Python进行Face Alignment。
调整你的超参数
我的第二个建议是,您尝试在您正在使用的任何机器学习模型上调整您的超参数(即,在提取的面部嵌入之上训练的模型)。
在本教程中,我们使用了线性SVM; 但是,我们没有调整 C 值,这通常是调整SVM的最重要的值。
该 Ç 值是一个“阈值”参数和控制你多么想避免在错误分类的训练集中的每个数据点。
较大的C值 将更严格,并且更加努力地对每个输入数据点进行正确分类,即使存在过度拟合的风险。
较小的C值 将更“软”,允许在训练数据中进行一些错误分类,但理想情况下更好地推广测试数据。
有趣的是,根据OpenFace GitHub中的一个分类示例,他们实际上建议不调整超参数,因为根据他们的经验,他们发现设置 C = 1 在大多数设置中获得令人满意的面部识别结果。
尽管如此,如果您的面部识别精度不够,通过网格搜索或随机搜索调整超参数可能需要额外的工作量和计算成本。
使用dlib的嵌入模型(但不是它的k-NN用于人脸识别)
根据我使用OpenCV的人脸识别模型和dlib的人脸识别模型的经验,我发现dlib的面部嵌入更具有辨别力,特别是对于较小的数据集。
k-NN模型运行得非常好,但正如我们所知,存在更强大的机器学习模型。
为了进一步提高准确性,你可能想要使用dlib的嵌入模型,然后不是应用k-NN,而是从今天的帖子开始遵循步骤#2,并在面部嵌入上训练更强大的分类器。
您是否遇到过运行今天Python面部识别脚本的“USAGE”错
我的错误看起来像这样
本教程中有三个单独的Python脚本,而且,每个脚本都要求您(正确)提供相应的命令行参数。
如果您是命令行参数的新手,那很好,但是 在尝试运行这些脚本之前, 您需要了解Python,argparse和命令行参数的工作原理!
我会诚实地对你说 – 面部识别是一种先进的技术。命令行参数是一个 非常初学者/新手的 概念。确保你在跑步前走路,否则你会绊倒。现在花些时间来教育自己如何使用命令行参数。
对于想要使用像Spyder的或PyCharm一个IDE读者我的建议是,您将学习如何在命令行中/终端使用命令行参数 第一。在IDE中编程,但使用命令行执行脚本。
摘要
在今天的博客文章中,我们使用 opencv 人脸识别 .
如果您需要帮助收集自己的面部数据集,请务必参考有关构建面部识别数据集的这篇文章。
安装OpenCV。可以参考我的教程 pip 安装 opencv
代码下载
请看 这篇文章 https://hotdog29.com/?p=620
请直接查看原文 OpenCV 人脸识别 源代码 https://hotdog29.com/?p=553
OpenCV 人脸识别 源代码相关推荐
- dlib 使用OpenCV,Python和深度学习进行人脸识别 源代码
请直接访问原文章 dlib 使用OpenCV,Python和深度学习进行人脸识别 源代码 https://hotdog29.com/?p=595 在 2019年7月7日 上张贴 由 hotdog发表回 ...
- 基于python opencv人脸识别的员工考勤系统
WorkAttendanceSystem 一个基于opencv人脸识别的员工考勤系统,作者某双一流A类大学里的一流学生,写于2018/09/,python课设期间. 源代码详细解释请关注微信公众号: ...
- 基于python opencv人脸识别的签到系统
基于python opencv人脸识别的签到系统 前言 先看下效果 实现的功能 开始准备 页面的构建 功能实现 代码部分 总结 前言 一个基于opencv人脸识别和TensorFlow进行模型训练的人 ...
- opencv 全志_移植opencv人脸识别到全志A10开发板上 +linux3.0内核
移植opencv人脸识别 libz: zlib-1.2.3 libjpeg: jpegsrc.v6b libpng: libpng-1.2.18 libyasm: yasm-0.7. ...
- python人脸照片分类_Python OpenCV 人脸识别(一)
前面介绍了Numpy模块,下面再介绍一个OpenCV模块,就基于这两个库看一下当下很火的人工智能是如何实现的,我们介绍几个:人脸识别(当下非常火的).音视频操作等等.今天先介绍一下静态图片的人脸识别, ...
- 图像识别——(java)opencv(人脸识别简单实现)
人脸识别 package com.acts.opencv.demo;import javax.servlet.http.HttpServletRequest; import javax.servlet ...
- Python+OpenCV人脸识别签到考勤系统(新手入门)
Python+OpenCV人脸识别签到考勤系统(新手入门) 前言 项目效果图 项目需要的环境 编译器 辅助开发QT-designer 项目配置 代码部分 核心代码 项目目录结构 后记 正式版改进 项目 ...
- python opencv人脸识别考勤系统的完整源码
这篇文章主要介绍了python opencv人脸识别考勤系统的完整源码,本文给大家介绍的非常详细,希望对大家的学习或工作具有一定的参考借鉴价值. 代码如下: import wx import wx.g ...
- openCV人脸识别简单案例
1 基础 我们使用机器学习的方法完成人脸检测,首先需要大量的正样本图像(面部图像)和负样本图像(不含面部的图像)来训练分类器.我们需要从其中提取特征.下图中的 Haar 特征会被使用,就像我们的卷积核 ...
最新文章
- python统计元素个数_python怎么统计列表中元素的个数
- ngx_http_lua_inject_socket_tcp_api函数代码注释
- LeetCode-二分查找-278. 第一个错误的版本
- JCO与bapi的联合使用
- 一周刷题记录 | WebMisc
- 10分钟!构建支持10万/秒请求的大型网站
- 获取硬盘总容量,柱面数,磁道数,扇区数
- 生命很短,我用tldr
- 数据分析之如何制作数据埋点文档
- php to golang,PHP To Go 转型手记 (二)
- UVA10267 Graphical Editor【模拟】
- Java编程思想精彩评注分享之二
- python中home定义是什么_搞清楚Python中self的含义
- spyder指定python环境
- 美国大学 计算机科学 排名,美国大学本科计算机专业排名TOP50榜单介绍
- echarts设置图标图例legend为圆,长方形,扇形等
- 【MineCraft】-- 如何开设我的世界服务器
- mongodb性能优化
- 【JavaScript】DOM和事件简介和文档加载流程以及DOM查询(上)案例(附源码)
- elasticSearch 中的查询关键词