利用Python实现眨眼计数器的示例代码

目录
  • 一、前言
  • 二、实现步骤
    • 1.第三方库
    • 2.导入视频文件并播放
    • 3.让视频循环播放
    • 4.创建面部检测器
    • 5.对眼睛周围的点进行标记
    • 6.观察眼睛宽度和长度变化并进行计数
  • 三、整体代码

一、前言

这几天宅在家里网上冲浪,无意间看到了一个比较有趣的项目,就是使用 Python 语言实现对视频中的人物的眨眼进行计数并描绘在图表中。我尝试了一下,发现是可以实现的,所以自己码了一遍代码并简单注释了一下,有兴趣的朋友可以浅试一下。

该项目大致效果如下:

Now, let's start!

二、实现步骤

对于创建项目文件夹配置环境以及如何安装第三方库这里就不再详细的介绍了,有不会的同学可以去翻我之前的文章或者其他博主的文章去了解学习吧,并不是很难。

1.第三方库

首先我们需要安装 cvzone(一个比较专业的计算机视觉包,在面部识别,手势、姿势检测中为我们提供了很多便利)。还有一个包是 mediapipe,我们将会使用它来实现面部检测网络,以便于对视频中的眼睛部位进行观察。

2.导入视频文件并播放

实现代码及效果如下:

import cv2
import cvzone

cap = cv2.VideoCapture('BlinkCounter.mp4')#获取需要检测的视频(添加视频路径即可,此处由于视频和Python文件在同一路径,直接调用即可)

while True:
    success, img = cap.read()
    img = cv2.resize(img, (640, 360)) #对图像尺寸进行调节
    cv2.imshow("Image", img)          #显示图像
    cv2.waitKey(1)

3.让视频循环播放

我们要对视频中的眨眼次数进行计数,但通过上面的代码可以看出视频很快就播放结束了,所以我们采用检查视频帧数的方式,当达到视频的最后一帧时对其进行重置,达到循环播放视频的目的。代码如下:

#------------------------------------------------------------
#检查当前帧数是否等于视频的总体帧数,如果相等,将播放帧数重置为0
#------------------------------------------------------------
    if cap.get(cv2.CAP_PROP_POS_FRAMES) == cap.get(cv2.CAP_PROP_FRAME_COUNT):
        cap.set(cv2.CAP_PROP_POS_FRAMES, 0)

4.创建面部检测器

该步骤需要使用到 cvzone 中的相应模块来实现,具体代码及注释如下:

import cv2
import cvzone
from cvzone.FaceMeshModule import FaceMeshDetector  #调用面部检测模块

cap = cv2.VideoCapture('BlinkCounter.mp4')#获取需要检测的视频(添加视频路径即可,此处由于视频和Python文件在同一路径,直接调用即可)
detector = FaceMeshDetector(maxFaces = 1)#创建人脸网络检测器,检测面部数量为1

while True:
#------------------------------------------------------------
#检查当前帧数是否等于视频的总体帧数,如果相等,将播放帧数重置为0
#------------------------------------------------------------
    if cap.get(cv2.CAP_PROP_POS_FRAMES) == cap.get(cv2.CAP_PROP_FRAME_COUNT):
        cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
#------------------------------------------------------------
    success, img = cap.read()
    img, faces = detector.findFaceMesh(img)#绘制人脸网络

    img = cv2.resize(img, (640, 360)) #对图像尺寸进行调节
    cv2.imshow("Image", img)          #显示图像
    cv2.waitKey(1)

得到的结果如下:

5.对眼睛周围的点进行标记

由于面部检测器是对面部用点进行标记的,所以我们需要找到那些眼睛周围的点并将它们使用特殊的点来进行标记,从而达到检测眼睛闭合与张开的目的,相应的点数以及代码如下:

idList = [22, 23, 24, 26, 110, 157, 158, 159, 160, 161, 130, 243]#面部检测器中眼眶周围的像素点

color = (0, 0, 255)#将颜色设置为红色

#------------------------------------------------------------
#检测到面部时将面部的关于眼眶的点用圆圈表示出来,并填补完整
#------------------------------------------------------------
    if faces:
        face = faces[0]
        for id in idList:
            cv2.circle(img, face[id], 5, color, cv2.FILLED)

得到的效果如下,可以看出,已经对眼眶进行了标记:

我们可以对面部检测网络进行设置,让其他的一些点不再显示出来,只关注我们的目标点,具体操作方式是只需要在函数中添加一个参数即可,效果如下:

img, faces = detector.findFaceMesh(img, draw = False)#绘制人脸检测网络,将参数 draw 修改为    False 即可抹去其他的不必要的点

6.观察眼睛宽度和长度变化并进行计数

如果单纯的靠上下眼皮的变化来检测是否眨眼会造成判断错误,所以我们需要结合眼睛长度和宽度之比进行判断。将这项数据的变化趋势绘制在一个窗口中,就会使得我们的观察更加明显,得到的效果也将更加优良。具体代码如下:

#-------------------------------------------------------------
#使用眼眶周围不同的点之间的距离以及眼睛宽度和长度的对比进行眨眼计数
#-------------------------------------------------------------
        leftUp = face[159]#定义不同部位的像素点
        leftDown = face[23]
        leftLeft = face[130]
        leftRight = face[243]
        lenghtVer, _ = detector.findDistance(leftUp, leftDown)#得到眼睛宽度
        lenghtHor, _ = detector.findDistance(leftLeft, leftRight)#得到眼睛长度

        cv2.line(img, leftUp, leftDown, (0, 200, 0), 3)#绘制与眼睛等宽的线段
        cv2.line(img, leftLeft, leftRight, (0, 200, 0), 3)#绘制与眼睛等长的线段

        ratio = int((lenghtVer / lenghtHor) * 100)#得到的数据并进行标准化,得到比率值

        ratioList.append(ratio)#使用比率值填补列表
        #------------------------------------------------------------------
        #从之前的一共三个比率中得到平均值,如果比率数目大于3将会删去前面的比率值
        #------------------------------------------------------------------
        if len(ratioList) > 3:
            ratioList.pop(0)
        ratioAvg = sum(ratioList) / len(ratioList)#得到比率平均值
        #------------------------------------
        #通过比率平均值的变化对眨眼次数进行计数
        #------------------------------------
        if ratioAvg < 35 and counter == 0:
            blinkCounter += 1#变化一次,计数器加一
            color = (0, 200, 0)
            counter = 1
        if counter != 0:
            counter += 1
            if counter > 10:
                counter = 0
                color = (255, 0, 255)
        #-----------------------------
        #编写文本框来记录眨眼的总体次数
        #------------------------------
        cvzone.putTextRect(img, f'Blink Count: {blinkCounter}', (50, 250),
                           12, colorR = color)

        imgPlot = plotY.update(ratioAvg, color)
        img = cv2.resize(img, (400, 640))  # 对图像尺寸进行调节
        imgStack = cvzone.stackImages([img, imgPlot], 2, 1)#将两幅图像放到一起,叠放为2列图像
    else:
        img = cv2.resize(img, (400, 640))  # 对图像尺寸进行调节
        imgStack = cvzone.stackImages([img, img], 2, 1)

通过以上步骤大致就能实现眨眼计数了。

三、整体代码

整体代码如下,已经添加了注释,如果有解释的不清楚的地方可以在评论区交流。

import cv2
import cvzone
from cvzone.FaceMeshModule import FaceMeshDetector
from cvzone.PlotModule import LivePlot

cap = cv2.VideoCapture('BlinkCounter.mp4')#获取需要检测的视频(添加视频路径即可,此处由于视频和Python文件在同一路径,直接调用即可)
detector = FaceMeshDetector(maxFaces = 1)#创建人脸网络检测器,检测面部数量为1
plotY = LivePlot(640, 640, [20, 50], invert = True)#创建窗口来绘制数据的变化

idList = [22, 23, 24, 26, 110, 157, 158, 159, 160, 161, 130, 243]#面部检测器中眼眶周围的像素点
ratioList = []#创建一个空的比率列表
blinkCounter = 0
counter = 0#避免每一个帧节进行一次计数

color = (0, 0, 255)#将颜色设置为红色

while True:
#------------------------------------------------------------
#检查当前帧数是否等于视频的总体帧数,如果相等,将播放帧数重置为0
#------------------------------------------------------------
    if cap.get(cv2.CAP_PROP_POS_FRAMES) == cap.get(cv2.CAP_PROP_FRAME_COUNT):
        cap.set(cv2.CAP_PROP_POS_FRAMES, 0)

    success, img = cap.read()#读取到的视频
    img, faces = detector.findFaceMesh(img, draw = False)#绘制人脸检测网络
#------------------------------------------------------------
#检测到面部时将面部的关于眼眶的点用圆圈表示出来,并填补完整
#------------------------------------------------------------
    if faces:
        face = faces[0]
        for id in idList:
            cv2.circle(img, face[id], 5, color, cv2.FILLED)
#-------------------------------------------------------------
#使用眼眶周围不同的点之间的距离以及眼睛宽度和长度的对比进行眨眼计数
#-------------------------------------------------------------
        leftUp = face[159]#定义不同部位的像素点
        leftDown = face[23]
        leftLeft = face[130]
        leftRight = face[243]
        lenghtVer, _ = detector.findDistance(leftUp, leftDown)#得到眼睛宽度
        lenghtHor, _ = detector.findDistance(leftLeft, leftRight)#得到眼睛长度

        cv2.line(img, leftUp, leftDown, (0, 200, 0), 3)#绘制与眼睛等宽的线段
        cv2.line(img, leftLeft, leftRight, (0, 200, 0), 3)#绘制与眼睛等长的线段

        ratio = int((lenghtVer / lenghtHor) * 100)#得到的数据并进行标准化,得到比率值

        ratioList.append(ratio)#使用比率值填补列表
        #------------------------------------------------------------------
        #从之前的一共三个比率中得到平均值,如果比率数目大于3将会删去前面的比率值
        #------------------------------------------------------------------
        if len(ratioList) > 3:
            ratioList.pop(0)
        ratioAvg = sum(ratioList) / len(ratioList)#得到比率平均值
        #------------------------------------
        #通过比率平均值的变化对眨眼次数进行计数
        #------------------------------------
        if ratioAvg < 35 and counter == 0:
            blinkCounter += 1#变化一次,计数器加一
            color = (0, 200, 0)
            counter = 1
        if counter != 0:
            counter += 1
            if counter > 10:
                counter = 0
                color = (255, 0, 255)
        #-----------------------------
        #编写文本框来记录眨眼的总体次数
        #------------------------------
        cvzone.putTextRect(img, f'Blink Count: {blinkCounter}', (50, 250),
                           12, colorR = color)

        imgPlot = plotY.update(ratioAvg, color)
        img = cv2.resize(img, (400, 640))  # 对图像尺寸进行调节
        imgStack = cvzone.stackImages([img, imgPlot], 2, 1)#将两幅图像放到一起,叠放为2列图像
    else:
        img = cv2.resize(img, (400, 640))  # 对图像尺寸进行调节
        imgStack = cvzone.stackImages([img, img], 2, 1)

    img = cv2.resize(img, (400, 640)) #对图像尺寸进行调节
    cv2.imshow("Image", imgStack)
    cv2.waitKey(1)

以上就是利用Python实现眨眼计数器的示例代码的详细内容,更多关于Python眨眼计数器的资料请关注我们其它相关文章!

(0)

相关推荐

  • OpenCV-Python模板匹配人眼的实例

    什么是模板匹配 模板匹配是指在当前图像A内寻找与图像B最相似的部分,可以理解找茬,但是这里是找出一样的信息. 一般我们将图像A称为输入图像,将图像B称为模板图像.模板匹配的原理就是将模板B图像在图像A上滑动遍历,找出与其匹配的部分. 模板匹配函数 在OpenCV中,它给我们提供了cv2.matchTemplate()函数来完成模板匹配.其函数的完整定义如下: def matchTemplate(image, templ, method, result=None, mask=None): imag

  • 基于python3+OpenCV实现人脸和眼睛识别

    基于python3+OpenCV的人脸和眼睛识别,供大家参考,具体内容如下 一.OpenCV人脸检测的xml文件下载 人脸检测和眼睛检测要用到haarcascade_eye.xml和haarcascade_frontalface_default.xml这两个文件,这两个文件可以在OpenCV的官网下载,具体下载方法如下: 1.打开要下载的xml文件,如下图: 2.点击Raw: 3.在新打开的网页中右击,选择另存为,最后保存就可以了. 二.人脸检测文件的导入以及图片的处理 接下来就可以在代码中载入

  • 基于Python OpenCV和 dlib实现眨眼检测

    目录 了解"眼睛纵横比"(EAR) 使用面部标志和 OpenCV 检测眨眼 眨眼检测结果 总结 今天,我们使用面部标记和 OpenCV 检测视频流中的眨眼次数. 为了构建我们的眨眼检测器,我们将计算一个称为眼睛纵横比 (EAR) 的指标,该指标由 Soukupová 和 Čech 在他们 2016 年的论文<使用面部标记的实时眨眼检测>中介绍. 与计算眨眼的传统图像处理方法不同,传统的图像处理方法通常涉及以下某些组合: 眼睛定位. 阈值以找到眼白. 确定眼睛的"白

  • 基于python+opencv调用电脑摄像头实现实时人脸眼睛以及微笑识别

    本文教大家调用电脑摄像头进行实时人脸+眼睛识别+微笑识别,供大家参考,具体内容如下 一.调用电脑摄像头进行实时人脸+眼睛识别 # 调用电脑摄像头进行实时人脸+眼睛识别,可直接复制粘贴运行 import cv2 face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades+'haarcascade_frontalface_default.xml') eye_cascade = cv2.CascadeClassifier(cv2.data.ha

  • Python+OpenCV实现实时眼动追踪的示例代码

    使用Python+OpenCV实现实时眼动追踪,不需要高端硬件简单摄像头即可实现,效果图如下所示. 项目演示参见:https://www.bilibili.com/video/av75181965/ 项目主程序如下: import sys import cv2 import numpy as np import process from PyQt5.QtCore import QTimer from PyQt5.QtWidgets import QApplication, QMainWindow

  • 利用Python实现眨眼计数器的示例代码

    目录 一.前言 二.实现步骤 1.第三方库 2.导入视频文件并播放 3.让视频循环播放 4.创建面部检测器 5.对眼睛周围的点进行标记 6.观察眼睛宽度和长度变化并进行计数 三.整体代码 一.前言 这几天宅在家里网上冲浪,无意间看到了一个比较有趣的项目,就是使用 Python 语言实现对视频中的人物的眨眼进行计数并描绘在图表中.我尝试了一下,发现是可以实现的,所以自己码了一遍代码并简单注释了一下,有兴趣的朋友可以浅试一下. 该项目大致效果如下: Now, let's start! 二.实现步骤

  • 利用Python实现简易计算器的示例代码

    目录 实现流程 代码实现 定义函数 输入值 判断运算 全部代码展示 运行展示 最近学习了字符串,运算符,条件语句,循环语句,我在想可以用我最近学的东西做什么? 看到运算我就想到了可以做一个简易的计算器. 实现流程 1.定义函数 2.请用户选择运算方法 3.请用户输入要运算的两个数 4.运算出结果 代码实现 定义加减乘除四种函数,在后续的运算中调用这四个函数输出结果. 定义加减乘除四种运算的函数 定义函数要用def 首先定义加法函数add在里面传入参数x,y   返回值X加y 定义subtract

  • Java利用Redis实现高并发计数器的示例代码

    业务需求中经常有需要用到计数器的场景:譬如一个手机号一天限制发送5条短信.一个接口一分钟限制多少请求.一个接口一天限制调用多少次等等.使用Redis的Incr自增命令可以轻松实现以上需求.以一个接口一天限制调用次数为例: /** * 是否拒绝服务 * @return */ private boolean denialOfService(String userId){ long count=JedisUtil.setIncr(DateUtil.getDate()+"&"+user

  • Python利用numpy实现三层神经网络的示例代码

    本文主要介绍了Python利用numpy实现三层神经网络的示例代码,分享给大家,具体如下: 其实神经网络很好实现,稍微有点基础的基本都可以实现出来.主要都是利用上面这个公式来做的. 这是神经网络的整体框架,一共是三层,分为输入层,隐藏层,输出层.现在我们先来讲解下从输出层到到第一个隐藏层. 使用的编译器是jupyter notebook import numpy as np #定义X,W1,B1 X = np.array([1.0, 0.5]) w1 = np.array([[0.1, 0.3,

  • 拿来就用!Python批量合并PDF的示例代码

    大家好,今天分享一个实用的办公脚本:将多个PDF合并为一个PDF,例如我手上现在有如下3个PDF分册,需要整合成一个完整的PDF 如果换成你操作的话,是不是打开百度搜索:PDF合并,然后去第三方网站操作,可能会收费不说还担心文件泄漏,现在有请Python出场,简单快速,光速合并,拿走就用! 首先导入需要的库和路径设置 import os from PyPDF2 import PdfFileReader, PdfFileWriter if __name__ == '__main__': # 设置存

  • Python实现端口扫描器的示例代码

    目录 socket概念 socket基本用法 创建tcp套接字 实现端口扫描 socket概念 socket又称套接字,可以看做是不同主机之间的进程进⾏双向通信的端点,简单的说就是通信的两⽅的⼀种约定,⽤套接字中的相关函数来完成通信过程,发出网络请求或者应答网络请求. socket起源于Unix,⽽Unix/Linux基本哲学之⼀就是"⼀切皆⽂件",对于⽂件⽤"打开"."读写"."关闭"模式来操作.而socket就是该模式的⼀

  • 利用OpenCV进行对象跟踪的示例代码

    目录 OpenCV 对象跟踪 OpenCV 对象跟踪器 物体跟踪 总结 OpenCV 对象跟踪 这篇文章使用 OpenCV 中内置的八种不同的对象跟踪算法,实现对物体的跟踪. 首先,介绍一下8种跟踪算法. 然后,演示如何使用OpenCV实现这些跟踪算法. 最后,对本文做总结. OpenCV 对象跟踪器 OpenCV 八种对象跟踪器: BOOSTING Tracker:基于用于驱动 Haar 级联 (AdaBoost) 背后的机器学习的相同算法,但与 Haar 级联一样,已有十多年的历史.这个跟踪

  • 基于Python实现围棋游戏的示例代码

    目录 1.导入模块 2.初始化棋盘 3. 开始游戏 4.放弃当前回合落子 5.悔棋判断 6.重新开始 7.右侧太极图的设置 8.落子设置 9.吃子规则判定设置 10.其他 11.程序入口 12.效果图 文件自取 1.导入模块 tkinter:ttk覆盖tkinter部分对象,ttk对tkinter进行了优化 copy:深拷贝时需要用到copy模块 tkinter.messagebox:围棋应用对象定义 如没有以上模块,在pycharm终端输入以下指令: pip install 相应模块 -i h

  • 利用Python创建位置生成器的示例详解

    目录 介绍 开始 步骤 创建训练数据集 创建测试数据集 将合成图像转换回坐标 放在一起 结论 介绍 在这篇文章中,我们将探索如何在美国各地城市的地图数据和公共电动自行车订阅源上训练一个快速生成的对抗网络(GAN)模型. 然后,我们可以通过为包括东京在内的世界各地城市创建合成数据集来测试该模型的学习和概括能力. git clone https://github.com/gretelai/GAN-location-generator.git 在之前的一篇博客中,我们根据电子自行车订阅源中的精确位置数

  • 利用Python自动生成PPT的示例详解

    在日常工作中,PPT制作是常见的工作,如果制作创意类PPT,则无法通过自动化的形式生成,因为创意本身具有随机性,而自动化解决的是重复性工作,两者有所冲突. python-pptx是python处理PPT的一个库,注重的是读和写,无法导出,没有渲染功能. 废话不多说,第一步,安装python-pptx库: pip3 install -i https://pypi.doubanio.com/simple/ python-pptx ppt里面处理的主要对象一般为文本框,表格,图片. 每一页的ppt为一

随机推荐