基于python语言dlib库和opencv库的视频眨眼检测

news2024/11/20 18:47:08

功能说明:

基于python编程语言,使用dlib 和opencv开发的视频眨眼检测。

环境:

*   python 3.6.8
*   opencv 3.4.2.16
*   dlib 19.7.0

原理:

1.使用opencv-python读取处理视频图像

2.使用线程机制处理人脸检测关键点

3.根据dlib算法检测到的关键点计算眼部特征,通过欧氏距离计算确定是睁眼还是闭眼

4.统计闭眼次数并在视频图片中绘制结果

原始代码:

# 基于opencv-python和dlib库的视频眨眼检测

# 导入工具包
from scipy.spatial import distance as dist
from collections import OrderedDict
import numpy as np
import argparse
import time
# pip install dlib==19.6.1 -i https://mirrors.aliyun.com/pypi/simple
import dlib
# pip install opencv-python==3.4.1
import cv2

# 关键点排序
FACIAL_LANDMARKS_68_IDXS = OrderedDict([
    ("mouth", (48, 68)),
    ("right_eyebrow", (17, 22)),
    ("left_eyebrow", (22, 27)),
    ("right_eye", (36, 42)),
    ("left_eye", (42, 48)),
    ("nose", (27, 36)),
    ("jaw", (0, 17))
])


# http://vision.fe.uni-lj.si/cvww2016/proceedings/papers/05.pdf
def eye_aspect_ratio(eye):
    """
    计算眼睛上下关键点欧式距离
    :param eye:眼睛关键点位置
    :return: 眼睛睁开程度
    """
    # 计算距离,竖直的
    A = dist.euclidean(eye[1], eye[5])
    B = dist.euclidean(eye[2], eye[4])
    # 计算距离,水平的
    C = dist.euclidean(eye[0], eye[3])
    # ear值
    ear = (A + B) / (2.0 * C)
    return ear


# 输入参数
ap = argparse.ArgumentParser()
ap.add_argument("-p", "--shape-predictor", required=True,
                help="path to facial landmark predictor")
ap.add_argument("-v", "--video", type=str, default="",
                help="path to input video file")
args = vars(ap.parse_args())
print(args)
# 设置判断参数
EYE_AR_THRESH = 0.3 # 低于该值则判断为眨眼
EYE_AR_CONSEC_FRAMES = 3

# 初始化计数器
COUNTER = 0
TOTAL = 0

# 检测与定位工具
print("[INFO] loading facial landmark predictor...")
detector = dlib.get_frontal_face_detector()
#predictor = dlib.shape_predictor(args["shape_predictor"])
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
# 分别取两个眼睛区域
(lStart, lEnd) = FACIAL_LANDMARKS_68_IDXS["left_eye"]
(rStart, rEnd) = FACIAL_LANDMARKS_68_IDXS["right_eye"]

# 读取视频
print("[INFO] starting video stream thread...")
#vs = cv2.VideoCapture(args["video"])
vs = cv2.VideoCapture(0)
#vs = FileVideoStream(args["video"]).start()
time.sleep(1.0)


def shape_to_np(shape, dtype="int"):
    # 创建68*2
    coords = np.zeros((shape.num_parts, 2), dtype=dtype)
    # 遍历每一个关键点
    # 得到坐标
    for i in range(0, shape.num_parts):
        coords[i] = (shape.part(i).x, shape.part(i).y)
    return coords


# 遍历每一帧
while True:
    # 预处理
    frame = vs.read()[1]
    if frame is None:
        break

    (h, w) = frame.shape[:2]
    width = 1200
    r = width / float(w)
    dim = (width, int(h * r))
    frame = cv2.resize(frame, dim, interpolation=cv2.INTER_AREA)
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # 检测人脸
    rects = detector(gray, 0)

    # 遍历每一个检测到的人脸
    for rect in rects:
        # 获取坐标
        shape = predictor(gray, rect)
        shape = shape_to_np(shape)

        # 分别计算ear值
        leftEye = shape[lStart:lEnd]
        rightEye = shape[rStart:rEnd]
        leftEAR = eye_aspect_ratio(leftEye)
        rightEAR = eye_aspect_ratio(rightEye)

        # 算一个平均的
        ear = (leftEAR + rightEAR) / 2.0

        # 绘制眼睛区域
        leftEyeHull = cv2.convexHull(leftEye)
        rightEyeHull = cv2.convexHull(rightEye)
        cv2.drawContours(frame, [leftEyeHull], -1, (0, 255, 0), 1)
        cv2.drawContours(frame, [rightEyeHull], -1, (0, 255, 0), 1)

        # 检查是否满足阈值
        if ear < EYE_AR_THRESH:
            COUNTER += 1

        else:
            # 如果连续几帧都是闭眼的,总数算一次
            if COUNTER >= EYE_AR_CONSEC_FRAMES:
                TOTAL += 1

            # 重置
            COUNTER = 0

        # 显示
        cv2.putText(frame, "Blinks: {}".format(TOTAL), (10, 30),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
        cv2.putText(frame, "EAR: {:.2f}".format(ear), (300, 30),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)

    cv2.imshow("Frame", frame)
    key = cv2.waitKey(10) & 0xFF

    if key == 27:
        break

vs.release()
cv2.destroyAllWindows()

运行该代码进行调用摄像头检测和读取本地视频检测的命令如下:

python detect_blinks.py -p shape_predictor_68_face_landmarks.dat -v test.mp4
python detect_blinks.py -p shape_predictor_68_face_landmarks.dat -v 0

原始代码需要借助于命令行参数才可以运行,后来经过修改后,可以直接在编译器中运行的,代码如下:

# 视频眨眼检测
# 导入工具包
from scipy.spatial import distance as dist
from collections import OrderedDict
import numpy as np
import argparse
import time
# pip install dlib==19.6.1 -i https://mirrors.aliyun.com/pypi/simple
import dlib
# pip install opencv-python==3.4.1
import cv2

# 关键点排序
FACIAL_LANDMARKS_68_IDXS = OrderedDict([
    ("mouth", (48, 68)),
    ("right_eyebrow", (17, 22)),
    ("left_eyebrow", (22, 27)),
    ("right_eye", (36, 42)),
    ("left_eye", (42, 48)),
    ("nose", (27, 36)),
    ("jaw", (0, 17))
])


# http://vision.fe.uni-lj.si/cvww2016/proceedings/papers/05.pdf
def eye_aspect_ratio(eye):
    """
    计算眼睛上下关键点欧式距离
    :param eye:眼睛关键点位置
    :return: 眼睛睁开程度
    """
    # 计算距离,竖直的
    A = dist.euclidean(eye[1], eye[5])
    B = dist.euclidean(eye[2], eye[4])
    # 计算距离,水平的
    C = dist.euclidean(eye[0], eye[3])
    # ear值
    ear = (A + B) / (2.0 * C)
    return ear
    
# 设置判断参数
EYE_AR_THRESH = 0.3 # 低于该值则判断为眨眼
EYE_AR_CONSEC_FRAMES = 3

# 初始化计数器
COUNTER = 0
TOTAL = 0

# 检测与定位工具
print("[INFO] loading facial landmark predictor...")
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')

# 分别取两个眼睛区域
(lStart, lEnd) = FACIAL_LANDMARKS_68_IDXS["left_eye"]
(rStart, rEnd) = FACIAL_LANDMARKS_68_IDXS["right_eye"]

# 读取视频
print("[INFO] starting video stream thread...")
vs = cv2.VideoCapture(0)
time.sleep(1.0)


def shape_to_np(shape, dtype="int"):
    # 创建68*2
    coords = np.zeros((shape.num_parts, 2), dtype=dtype)
    # 遍历每一个关键点
    # 得到坐标
    for i in range(0, shape.num_parts):
        coords[i] = (shape.part(i).x, shape.part(i).y)
    return coords


# 遍历每一帧
while True:
    # 预处理
    frame = vs.read()[1]
    if frame is None:
        break

    (h, w) = frame.shape[:2]
    width = 1200
    r = width / float(w)
    dim = (width, int(h * r))
    frame = cv2.resize(frame, dim, interpolation=cv2.INTER_AREA)
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # 检测人脸
    rects = detector(gray, 0)

    # 遍历每一个检测到的人脸
    for rect in rects:
        # 获取坐标
        shape = predictor(gray, rect)
        shape = shape_to_np(shape)

        # 分别计算ear值
        leftEye = shape[lStart:lEnd]
        rightEye = shape[rStart:rEnd]
        leftEAR = eye_aspect_ratio(leftEye)
        rightEAR = eye_aspect_ratio(rightEye)

        # 算一个平均的
        ear = (leftEAR + rightEAR) / 2.0

        # 绘制眼睛区域
        leftEyeHull = cv2.convexHull(leftEye)
        rightEyeHull = cv2.convexHull(rightEye)
        cv2.drawContours(frame, [leftEyeHull], -1, (0, 255, 0), 1)
        cv2.drawContours(frame, [rightEyeHull], -1, (0, 255, 0), 1)

        # 检查是否满足阈值
        if ear < EYE_AR_THRESH:
            COUNTER += 1

        else:
            # 如果连续几帧都是闭眼的,总数算一次
            if COUNTER >= EYE_AR_CONSEC_FRAMES:
                TOTAL += 1

            # 重置
            COUNTER = 0

        # 显示
        cv2.putText(frame, "Blinks: {}".format(TOTAL), (10, 30),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
        cv2.putText(frame, "EAR: {:.2f}".format(ear), (300, 30),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)

    cv2.imshow("Frame", frame)
    key = cv2.waitKey(10) & 0xFF

    if key == 27:
        break

vs.release()
cv2.destroyAllWindows()

检测效果如下:

下载链接:https://mp.csdn.net/mp_download/manage/download/UpDetailed

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/502131.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Midjourney 5.1震撼更新!逼真到给跪,中国情侣细节惊艳,3D视频大片马上来

来源 | 新智元 作者 | 桃子&#xff0c;拉燕 一个月前&#xff0c;Midjourney V5画的一对中国完美情侣在网上爆火&#xff0c;让许多人纷纷惊呼画师要失业了。 恰在今天&#xff0c;Midjourney官宣V5能免费用了&#xff0c;而且还是最新版本V5.1。 各个大模型的研究测试传送门 …

Android 13 变更及适配攻略

准备工作 首先将我们项目中的 targetSdkVersion和compileSdkVersion 升至 33。 影响Android 13上所有应用 1.通知受限 对新安装的应用的影响&#xff1a; 如果用户在搭载 Android 13 或更高版本的设备上安装您的应用&#xff0c;应用的通知默认处于关闭状态。在您请求新的…

ChatGPT如何生成可视化图表-示例中国近几年出生人口

本教程收集于&#xff1a;AIGC从入门到精通教程汇总 ChatGPT本身不能直接生成可视化图表&#xff0c;但可以配合其他可视化工具或库 方法一&#xff1a;前端可视化开发库 Echarts&#xff08;地址&#xff1a;Apache ECharts &#xff09; 方法二&#xff1a;现有Python库。…

dump_stack分析函数调用关系实例及其实现

dump_stack分析函数调用关系 文章目录 dump_stack分析函数调用关系一、dump_stack实例二、dump_stack实现分析Step 1: dump_stack_print_infoStep 2: show_stack 三、关于堆栈 一、dump_stack实例 在正点原子阿尔法开发板中查看insmod命令使用什么方法&#xff1a; #include …

[蓝帽杯 2022 初赛]之Misc篇(NSSCTF)刷题记录(复现)⑨

NSSCTF-Misc篇-[蓝帽杯 2022 初赛] 计算机取证&#xff1a;[蓝帽杯 2022 初赛]计算机取证_1[蓝帽杯 2022 初赛]计算机取证_2[蓝帽杯 2022 初赛]计算机取证_3[蓝帽杯 2022 初赛]计算机取证_4 手机取证&#xff1a;[蓝帽杯 2022 初赛]手机取证_1[蓝帽杯 2022 初赛]手机取证_2 网站…

使用堆视图创建3个按钮三角摆放

使用堆视图创建3个按钮三角摆放 效果如图&#xff1a; 分析 从效果图看&#xff0c;想要让3个Button呈三角摆放&#xff0c;需要两个堆视图完成。 首先外部一个大的“垂直堆”&#xff0c;垂直堆第一项放一个Button&#xff0c;第二项放一个“水平堆” 水平堆里再放两个But…

刚入职领导就要求做自动化测试?我懵了,从业务到框架设计总结...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Python自动化测试&…

深度学习的环境搭建(window+pytorch)

1.检查是否安装CUDA CUDA&#xff08;Compute Unified Device Architecture&#xff09;是由 NVIDIA 推出的一种并行计算平台和编程模型&#xff0c;用于利用 NVIDIA GPU&#xff08;Graphics Processing Unit&#xff09;的强大计算能力进行高性能计算任务。CUDA 的主要特点是…

logstash介绍和使用-ELK文章2

官方 Logstash 是免费且开放的服务器端数据处理管道&#xff0c;能够从多个来源采集数据&#xff0c;转换数据&#xff0c;然后将数据发送到您最喜欢的“存储库”中。 下载和文档&#xff1a;https://www.elastic.co/cn/logstash/ docker部署&#xff1a;https://hub.docker.…

教你快速把heic格式转化jpg,4种方法操作简单

教你快速把heic格式转化jpg的方法&#xff0c;因为HEIC格式图片通常出现在苹果公司的iOS 11操作系统及之后的版本中&#xff0c;这是因为苹果公司在这些版本中采用了HEIF&#xff08;高效图像格式&#xff09;作为默认的照片格式来替代JPEG格式。同时&#xff0c;需要注意的是&…

asp.net+sqlserver社区小区流动人口管理系统

该系统的基本功能包括用户登录&#xff0c;管理员信息管理&#xff0c;社区组织管理&#xff0c;常住人口管理&#xff0c;流动人口管理&#xff0c;社区事务管理&#xff0c;社区服务管理&#xff0c;系统用户管理&#xff0c;修改密码等功能。 &#xff08;3&#xff09;功能…

项目分析v2

用户&#xff1a; 登录&#xff1a; 不能重复登录。 在服务端使用一个hashset记录用户的登录状态&#xff0c;如果用户id不在集合里面&#xff0c;就可以登录&#xff0c;登录时将用户id添加到集合中。用户下线时&#xff0c;将set中的元素删除。 登录成功后&#xff0c;服务端…

【语义分割】LinkNet从0到1和代码实现

文章目录 前言1.网络结构1.1 网络结构示意图1.2 创建LinkNet模型 2.代码2.1 各模块搭建2.1.1 卷积模块2.1.2 反卷积模块2.1.3 编码器模块 2.2 编码网络结构2.3 损失函数&训练2.4 训练 前言 已经有了U-net了&#xff0c;为什么需要linkNet&#xff1f; unet见这个文章【语义…

Docker基础篇(很详细)

一、简单介绍 &#xff08;一&#xff09;为什么用docker 开发人员发开完成就发布一个jar或者war包&#xff0c;其他的都交给运维人员来做&#xff1b;而现在&#xff0c;开发即运维&#xff0c;打包部署上线一套流程走完&#xff1a;开发人员会将项目及其附带的环境一起打包j…

UML类图使用介绍

文章目录 一、UML图1、什么是UML图2、类图概述3、类图的作用 二、类的表示方式举个栗子 三、类与类之间关系的表示方式1、关联关系&#xff08;1&#xff09;单向关联&#xff08;2&#xff09;双向关联&#xff08;3&#xff09;自关联 2、聚合关系3、组合关系4、依赖关系5、继…

安全加密基础—基本概念、keytool、openssl

前言 &#xff08;1&#xff09;本文不涉及源码、底层。只是讲解大概的密码演变过程和基本概念。能让接触到相关名词的人知道这些名词是干嘛的&#xff0c;为什么要有它。专业人士可以当作概念梳理&#xff0c;非专业人士可以当作科普。 &#xff08;2&#xff09;本文你将了解…

亿发工业互联网智能制造ERP系统,生产工厂信息化建设解决方案

亿发工业互联网智能制造ERP系统&#xff0c;生产工厂信息化建设解决方案 随着制造水平的发展&#xff0c;传统工厂原有的生产组织模式和质量管理模式已不能满足先进制造水平的要求。确保公司战略目标的实现&#xff0c;有必要借助信息技术加强对各种业务流程的管理。而企业走向…

Leetcode506. 相对名次

Every day a leetcode 题目来源&#xff1a;506. 相对名次 解法1&#xff1a;STL vector 自定义排序 使用 vector<pair<int, int>> 数组v记录原来 score 数组的下标和成绩。 对v按成绩进行降序排序。 新建一个 vector<string> 数组 ans&#xff0c;遍历…

WiFi(Wireless Fidelity)基础(三)

目录 一、基本介绍&#xff08;Introduction&#xff09; 二、进化发展&#xff08;Evolution&#xff09; 三、PHY帧&#xff08;&#xff08;PHY Frame &#xff09; 四、MAC帧&#xff08;MAC Frame &#xff09; 五、协议&#xff08;Protocol&#xff09; 六、安全&#x…

FP斗篷,2023独立站必看指南

Cloak斗篷技术是一种网络隐身术&#xff0c;通过技术手段实现在网络上匿名和隐身&#xff0c;保护个人隐私和安全。斗篷技术的实现原理是通过使用虚拟专用网络&#xff08;VPN&#xff09;或代理服务器等技术&#xff0c;将用户的真实IP地址隐藏起来&#xff0c;使其在网络上的…