摘要: 图像识别的新思路:眼睛纵横比,看看大牛如果用这种思路玩转识别眨眼动作!

今天我们来使用面部标志和OpenCV 检测和计算视频流中的眨眼次数。

为了构建我们的眨眼检测器,我们将计算一个称为眼睛纵横比(EAR)的指标

今天介绍的这个方法与传统的计算眨眼图像处理方法是不同的,使用眼睛的长宽比是更为简洁的解决方案,它涉及到基于眼睛的面部标志之间的距离比例是一个非常简单的计算。

用OpenCV,Python和dlib进行眼睛眨眼检测

我们的眨眼检测实验分为四个部分:

第一步,我们将讨论眼睛的纵横比以及如何用它来确定一个人是否在给定的视频帧中闪烁。

第二步,我们将编写Python,OpenCV和dlib代码来执行面部标志检测和检测视频流中的眨眼。

第三步,基于代码,我们将应用我们的方法来检测示例摄像头流中的眨眼以及视频文件。

最后,我将通过讨论改进我们的眨眼检测器的方法来结束。

1.了解“眼睛纵横比”(EAR)

我们可以应用面部标志检测来定位脸部的重要区域,包括眼睛,眉毛,鼻子,耳朵和嘴巴:

这也意味着我们可以通过了解特定脸部的索引来提取特定的脸部结构:

在眨眼检测方面,我们眼睛结构感兴趣。

每只眼睛由6个(x,y)坐标表示,从眼睛的左角开始,然后围绕该区域的其余部分顺时针显示:

基于这个描述,我们应该抓住重点:这些坐标的宽度和高度之间有一个关系。

Soukupová和Čech在其2016年的论文“使用面部标志实时眼睛眨眼检测”的工作,我们可以推导出反映这种关系的方程,称为眼睛纵横比(EAR):

其中p1,...,p6是2D面部地标位置。

这个方程的分子是计算垂直眼睛标志之间的距离,而分母是计算水平眼睛标志之间的距离,因为只有一组水平点,但是有两组垂直点,所以进行加权分母。

为什么这个方程如此有趣?

我们将会发现,眼睛的长宽比在眼睛张开的时候大致是恒定的,但是在发生眨眼时会迅速下降到零。

使用这个简单的方程,我们可以避免使用图像处理技术,简单地依靠眼睛地标距离的比例来确定一个人是否眨眼。

为了更清楚地说明,看下面的图:

在底部图中绘出了眼纵横比随时间的视频剪辑的曲线图。正如我们所看到的,眼睛纵横比是恒定的,然后迅速下降到接近零,然后再增加,表明一个单一的眨眼已经发生。

2.用面部标志和OpenCV检测眨眼(代码篇)

请打开一个新文件并将其命名为detect_blinks.py。插入以下代码:

要访问磁盘上的视频文件(FileVideoStream)或内置的网络摄像头/ USB摄像头/Raspberry Pi摄像头模块(VideoStream),我们需要使用imutils库,它可以使OpenCV更容易工作。

如果您的系统上没有安装 imutils,请确保使用以下命令安装/升级:

pip install --upgrade imutils

注意:如果您正在使用Python虚拟环境(OpenCV安装教程),请确保使用 workon命令首先访问您的虚拟环境,然后安装/升级 imutils。

例外的是dlib库,如果您的系统上没有安装dlib,请按照我的dlib安装教程配置您的机器。

接下来,我们将定义eye_aspect_ratio函数:

这个函数接受单一的参数,即给定的眼睛面部标志的(x,y)坐标  。

A,B是计算两组垂直眼睛标志之间的距离,而C是计算水平眼睛标志之间的距离。

最后,将分子和分母相结合,得出最终的眼睛纵横比。然后将眼图长宽比返回给调用函数。

让我们继续解析我们的命令行参数:

detect_blinks.py脚本需要一个命令行参数,然后第二个是可选的参数:

1.--shape-predictor:这是dlib的预训练面部标志检测器的路径。

2.--video:它控制驻留在磁盘上的输入视频文件的路径。如果您想要使用实时视频流,则需在执行脚本时省略此开关。

我们现在需要设置两个重要的常量,您可能需要调整实现,并初始化其他两个重要的变量。

当确定视频流中是否发生眨眼时,我们需要计算眼睛的长宽比。

如果眼睛长宽比低于一定的阈值,然后超过阈值,那么我们将记录一个“眨眼” -EYE_AR_THRESH是这个阈值,我们默认它的值为 0.3,您也可以为自己的应用程序调整它。另外,我们有一个重要的常量,EYE_AR_CONSEC_FRAME,这个值被设置为 3,表明眼睛长宽比小于3时,接着三个连续的帧一定发生眨眼动作。

同样,取决于视频的帧处理吞吐率,您可能需要提高或降低此数字以供您自己实施。

接着初始化两个计数器,COUNTER是眼图长宽比小于EYE_AR_THRESH的连续帧的总数,而 TOTAL则是脚本运行时发生的眨眼的总次数。

现在我们的输入,命令行参数和常量都已经写好了,接着可以初始化dlib的人脸检测器和面部标志检测器:

dlib库使用一个预先训练的人脸检测器,该检测器基于对用于对象检测的定向梯度直方图+线性SVM方法的修改。然后,我们初始化的实际面部标志预测值predictor。

您可以在本博客文章中了解更多关于dlib的面部标志性探测器(即它是如何工作的,它在哪些数据集上进行了训练等)。

由dlib生成的面部标记遵循可索引列表,正如我所描述的那样:

63acaa1053536f8c5bb1e7b7c2688e7a1188217a

因此,我们可以确定为下面的左眼和右眼提取(x,y)坐标的起始和结束数组切片索引值:

使用这些索引,我们将能够毫不费力地提取眼部区域。

接下来,我们需要决定是否使用基于文件的视频流或实时USB/网络摄像头/ Raspberry Pi摄像头视频流:

如果您使用的是文件视频流,请保持原样。

如果您想使用内置摄像头或USB摄像头,取消注释:# vs = VideoStream(src=0).start()。

Raspberry Pi相机模块,取消注释:# vs = VideoStream(usePiCamera=True).start()。

如果您未注释上述两个,你可以取消注释# fileStream = False以及以表明你是不是从磁盘读取视频文件。

最后,我们已经完成了我们脚本的主要循环:

在while处我们开始从视频流循环帧。

如果我们正在访问视频文件流,并且视频中没有剩余的帧,我们从循环中断。

从我们的视频流中读取下一帧,然后调整大小并将其转换为灰度。然后,我们通过dlib内置的人脸检测器检测灰度帧中的人脸。

我们现在需要遍历帧中的每个面,然后对其中的每个面应用面部标志检测:

shape确定面部区域的面部标志,接着将这些(x,y)坐标转换成NumPy阵列。

使用我们之前在这个脚本中的数组切片技术,我们可以分别为左眼left eye和右眼提取(x,y)坐标,然后我们计算每只眼睛的眼睛长宽比  。

下一个代码块简单地处理可视化眼部区域的面部标志:

我们已经计算了我们的(平均的)眼睛长宽比,但是我们并没有真正确定是否发生了眨眼,这在下一部分中将得到关注:

第一步检查眼睛纵横比是否低于我们的眨眼阈值,如果是,我们递增指示正在发生眨眼的连续帧数。否则,我们将处理眼高宽比不低于眨眼阈值的情况,我们对其进行检查,看看是否有足够数量的连续帧包含低于我们预先定义的阈值的眨眼率。如果检查通过,我们增加总的闪烁次数。然后我们重新设置连续闪烁次数 COUNTER。

我们的最终代码块只是简单地处理在输出帧上绘制闪烁的次数,以及显示当前的眼图高宽比:

3.眨眼检测结果

在执行之前,请务必使用本指南“下载”源代码+示例视频+预训练的dlib面部标记预测器。

要将我们的眨眼检测器应用于示例视频,只需执行以下命令:

$python detect_blinks.py \

--shape-predictor shape_predictor_68_face_landmarks.dat \

--video blink_detection_demo.mp4

后来,在旅馆里,我记录下了眨眼检测器的实时流,并将其变成了屏幕录像。

要访问我的内置摄像头,我执行了下面的命令(注意取消注释正确的VideoStream类,如上所述):

4.改进我们的眨眼检测器

我们只关注眼睛纵横比作为定量指标,以确定一个人是否在视频流中眨了眨眼睛。

为了使我们的眨眼检测器更加强大的显示中可能挑战,Soukupová和Čech建议:为了改善我们的眨眼检测器,Soukupová和Čech建议构建眼长宽比(第N帧,第  N-6 帧和第  N + 6帧)的13维特征向量,然后将该特征向量馈送到线性SVM分类。

本文由阿里云云栖社区组织翻译。

文章原标题《eye-blink-detection-opencv-python-dlib》,

作者:Adrian Rosebrock

python中opencv怎么检测双眼_OpenCV/Python/dlib眨眼检测相关推荐

  1. python中opencv怎么检测双眼_OpenCVPython中的瞳孔检测

    我正在为我的学校项目做学生检测.这是我第一次使用OpenCV和Python,使用Python version 3.4.2和opencv3.1.0. 我用的是覆盆子皮黑相机,我得到了很好的图像. 但我不 ...

  2. python中opencv安装_怎么为python安装opencv模块-百度经验

    opencv可以方便的进行图片处理,因此,搞人工智能和计算机视觉的人猿,很有必要为自己的python安装一个opencv模块. 下面,我就介绍一下具体方法. 工具/原料 电脑 python 方法/步骤 ...

  3. 使用Python,OpenCV+OCR检测护照图像中的机器可读区域(MRZ Machine-Readable Zones)

    使用Python,OpenCV+OCR检测护照图像中的机器可读区域(MRZ Machine-Readable Zones) 1. 效果图 2. 原理 3. 源码 参考 这篇博客将介绍如何只使用基本的图 ...

  4. python opencv创建图像_使用Python中OpenCV库创建一幅图片的RGB通道图片

    我们知道,在使用PhotoShop进行图片的抠取.创建和存储选区.存储图像的色彩资料等复杂操作时,经常会用到一个功能,那就是"RGB"通道,它能从三原色角度对一幅图片进行精准处理. ...

  5. python安装opencv及检测是否安装成功

    python安装opencv及检测是否安装成功 代码: 安装: pip install opencv-python pip install opencv-contrib-python 检查是否安装成功 ...

  6. python的继承用法_【后端开发】python中继承有什么用法?python继承的用法详解

    本篇文章给大家带来的内容是关于python中继承有什么用法?python继承的用法详解,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 面向对象三大特征 1.封装:根据职责将属性和方法 ...

  7. python中的命名空间_深入理解Python中的命名空间和范围

    Python中的命名空间和范围 在Python中,每个包.模块.类.函数和方法函数都拥有一个"名称空间",其中解析了变量名称.下面本篇文章就来带大家认识一下Python中的命名空间 ...

  8. python中获取文件大小_如何在Python中获取文件大小

    python中获取文件大小 We can get file size in Python using the os module. 我们可以使用os模块在Python中获取文件大小. Python中的 ...

  9. python中的递归思想_〖Python〗-- 递归、面向对象初识及编程思想

    [递归.面向对象初识及编程思想] 一.递归 1.定义: 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. (1)递归就是在过程或函数里调用自身: (2)在使用递归策 ...

最新文章

  1. 实验吧 速度爆破
  2. Hadoop “Unable to load native-hadoop library for y
  3. 你真的理解“吃亏是福”么?
  4. npm命令的--save 与--save-dev
  5. activiti根据当前节点获取下一个UseTask节点
  6. Python可视化中的Matplotlib(6.散点图以及详细参数、为图形添加文字、注释、箭头以及它们的参数)
  7. 关于linux LVM的好图 (Logic Volume Management,逻辑卷管理)
  8. hdu 3641 数论 二分求符合条件的最小值数学杂题
  9. 如何给领导打造一款掌上财务管理驾驶舱?
  10. pytorch torch.normal
  11. idea重写接口没有@override_细说 Java Overload 与 Override 差别
  12. ElementUI:路由界面刷新后导航栏仍显示default-active不跟随路由变化
  13. 辉迅手机号码归属地查询软件 手机号码归属地 手机查询
  14. 什么是主数据?什么是主数据管理系统?
  15. 安卓实训项目源码_实训2019 | 联想云实训心得
  16. ad7606中文资料_AD7606
  17. facenet无法检测到的三张人脸照片
  18. 极客日报第 39 期:小米 11 不送充电器;阿里达摩院 2021 十大科技趋势发布!
  19. 水漆哪个品牌好?十大品牌水漆排行榜
  20. U盘安装CentOS 7.0图文详解教程

热门文章

  1. AIGW40N65H5英飞凌车规MOS管\原装现货\ASEMI代理
  2. git切换远程分支版本-checkout
  3. 类Trello的看板软件Planka
  4. 【HEOI2015】【BZOJ4031】小Z的房间
  5. svpwm在stm32中的实现,附完整工程
  6. LaTex插入图片以及图片出现一串图片路径文字解决方法
  7. matlab randperm函数
  8. mysql版本升级对数据的影响_MySQL数据库升级的一些坑
  9. 商品SPU SKU 属性 分类设计
  10. PHP排列运算符优先级,php运算符优先级顺序详解