【机器学习实战入门】使用OpenCV和Keras的驾驶员疲劳检测系统

在这里插入图片描述

嗜睡驾驶者警报系统

在这里插入图片描述
防止司机疲劳驾驶警报系统
中级 Python 项目 - 司机疲劳检测系统

疲劳检测是一种安全技术,能够预防因司机在驾驶过程中入睡而造成的事故。

本中级 Python 项目的目标是建立一个疲劳检测系统,该系统将检测到一个人的眼睛闭合了一段时间。当检测到疲劳时,该系统会向司机发出警报。

司机疲劳检测系统
在这个 Python 项目中,我们将使用 OpenCV 从网络摄像头获取图像,并将其输入到一个深度学习模型中,该模型将分类人的眼睛是“睁着”还是“闭着”。我们为这个 Python 项目采用的方法如下:

步骤 1 - 从相机接收图像作为输入。

步骤 2 - 检测图像中的人脸,并创建一个感兴趣区域 (ROI)。

步骤 3 - 从 ROI 中检测眼睛,并将其输入到分类器中。

步骤 4 - 分类器将对眼睛的状态进行分类,确定是睁着还是闭着。

步骤 5 - 计算得分以检查该人是否疲劳。

司机疲劳检测数据集
用于构建这个模型的数据集是我们自行创建的。为了构建数据集,我们编写了一个脚本,该脚本从相机捕获眼睛图像并存储在本地磁盘上。我们将这些图像按照“睁着”和“闭着”两个标签进行了分类。数据经过了手动清理,移除了对构建模型不必要的图片。数据集包括在不同光照条件下大约 7000 张人眼图像。在用我们的数据集训练模型后,我们附上了模型权重和模型架构文件“models/cnnCat2.h5”。

现在,您可以使用这个模型来分类一个人的眼睛是睁着还是闭着的。

另外,如果您想构建和训练您自己的模型,您可以下载数据集:如果您想要构建和训练自己的模型,可以下载数据集:链接: 驾驶员嗜睡检测数据集
数据介绍:
Driver Drowsiness Data
The dataset consists of 2900 images which include both normal and yawning images. Dataset is divided into training and testing, which is used in the project for training and testing respectively.

It is an excellent dataset for people who want to learn machine learning techniques for driver drowsiness detection.

Sample Data:
在这里插入图片描述

模型架构
我们使用的模型是基于 Keras 构建的卷积神经网络 (CNN)。卷积神经网络是一种专门用于图像分类的深度神经网络,其表现极其出色。CNN 通常包括一个输入层、一个输出层和一个可能包含多个隐藏层的结构。卷积操作使用一个滤波器在各层上进行 2D 矩阵乘法。

CNN 模型架构包含以下层:

  • 卷积层;32 个节点,内核大小为 3
  • 卷积层;32 个节点,内核大小为 3
  • 卷积层;64 个节点,内核大小为 3
  • 全连接层;128 个节点
  • 最终层也是一个全连接层,包含 2 个节点。除了输出层使用了 Softmax 激活函数外,所有的层都使用了 ReLU 激活函数。

项目先决条件
本 Python 项目需要一个网络摄像头来捕获图像。您需要在系统上安装 Python(推荐版本 3.6),然后使用 pip 安装必要的包。

  • OpenCV - pip install opencv-python(用于脸部和眼睛检测)
  • TensorFlow - pip install tensorflow(Keras 使用 TensorFlow 作为后端)
  • Keras - pip install keras(用于构建分类模型)
  • Pygame - pip install pygame(用于播放警报声)

执行司机疲劳检测的步骤
从提供的 zip 文件中下载司机疲劳检测系统的项目源代码,并将文件解压到您的系统中:: 司机疲劳检测项目代码链接

zip 文件的内容:
在这里插入图片描述

项目文件结构 - 中级 Python 项目

“Haar 级联文件”文件夹包含用于从图像中检测对象的 xml 文件。我们的情况下,用于检测人的脸部和眼睛。
models 文件夹包含我们的模型文件“cnnCat2.h5”,该文件是在卷积神经网络上训练的。
我们有一个音频文件“alarm.wav”,在检测到人感到疲劳时会播放。
“Model.py”文件包含了我们通过训练数据集构建分类模型的程序。您可以在这个文件中看到卷积神经网络的实现。
“Drowsiness_detection.py”是我们项目的主要文件。要开始检测过程,我们需要运行这个文件。

现在我们来逐步了解算法的工作原理。

步骤 1 - 从相机接收图像作为输入

使用网络摄像头,我们将接收图像作为输入。为了访问摄像头,我们创建了一个无限循环,该循环将捕获每一帧。我们使用 OpenCV 提供的方法 cv2.VideoCapture(0) 来访问摄像头并设置捕获对象 (cap)。cap.read() 会读取每一帧,并将其存储在 frame 变量中。

步骤 2 - 检测图像中的人脸并创建感兴趣区域 (ROI)

为了在图像中检测人脸,我们首先需要将图像转换为灰度图,因为 OpenCV 的对象检测算法接受灰度图像作为输入。检测对象时我们不需要颜色信息。我们将使用 Haar 级联分类器来检测人脸。这行代码用于设置我们的分类器:face = cv2.CascadeClassifier(‘路径到我们的 Haar 级联 xml 文件’)。然后我们使用 faces = face.detectMultiScale(gray) 来完成检测任务。它返回一个检测结果数组,包含检测对象的 x 和 y 坐标,以及边界框的高度和宽度。我们现在可以遍历所有检测到的人脸,并为每个人脸绘制边界框。

for (x,y,w,h) in faces:
    cv2.rectangle(frame, (x,y), (x+w, y+h), (100,100,100), 1 )

步骤 3 - 从 ROI 中检测眼睛并将其输入到分类器中

使用与检测人脸相同的程序来检测眼睛。首先,我们分别在 leye 和 reye 中设置眼睛的级联分类器,然后用 left_eye = leye.detectMultiScale(gray) 来检测左眼。接下来,我们需要从完整的图像中仅提取眼睛数据。通过提取眼睛的边界框,然后使用以下代码从帧中单独拉出眼睛图像,可以实现这一点。

l_eye = frame[ y : y+h, x : x+w ]

l_eye 仅包含眼睛的图像数据。这个数据将被输入到我们的 CNN 分类器中,该分类器将预测眼睛是睁着还是闭着。同样地,我们将利用 r_eye 提取右眼。

步骤 4 - 分类器将对眼睛是睁着还是闭着进行分类

我们使用 CNN 分类器来预测眼睛状态。为了将图像输入模型,需要执行某些操作,因为模型需要正确的维度才能开始工作。首先,我们使用 r_eye = cv2.cvtColor(r_eye, cv2.COLOR_BGR2GRAY) 将彩色图像转换为灰度图。然后,我们将图像大小调整为 2424 像素,因为我们的模型是在 2424 像素的图像上训练的,cv2.resize(r_eye, (24,24))。为了更好的收敛,我们对数据进行归一化处理 r_eye = r_eye/255(所有值都在 0-1 之间)。扩展维度以输入到分类器中。我们使用 model = load_model(‘models/cnnCat2.h5’) 加载我们的模型。现在使用模型预测每个眼睛的状态

lpred = model.predict_classes(l_eye)

如果 lpred[0] 的值为 1,说明眼睛是睁着的;如果 lpred[0] 的值为 0,则说明眼睛是闭着的。

步骤 5 - 计算得分以检查该人是否疲劳

得分基本上是用于判断一个人闭眼时间的一个值。如果两个眼睛都闭着,我们将不断增加得分;眼睛睁开时,我们则减少得分。使用 cv2.putText() 函数在屏幕上绘制结果,这将显示人的实时状态。

cv2.putText(frame, “Open”, (10, height-20), font, 1, (255,255,255), 1, cv2.LINE_AA )

例如,如果得分大于 15,这意味着人的眼睛闭合了一段时间。此时,我们将使用 sound.play() 发出警报声。

主文件的源代码如下所示:

import cv2
import os
from keras.models import load_model
import numpy as np
from pygame import mixer
import time
mixer.init()
sound = mixer.Sound('alarm.wav')
face = cv2.CascadeClassifier('haar cascade files\haarcascade_frontalface_alt.xml')
leye = cv2.CascadeClassifier('haar cascade files\haarcascade_lefteye_2splits.xml')
reye = cv2.CascadeClassifier('haar cascade files\haarcascade_righteye_2splits.xml')
lbl=['Close','Open']
model = load_model('models/cnncat2.h5')
path = os.getcwd()
cap = cv2.VideoCapture(0)
font = cv2.FONT_HERSHEY_COMPLEX_SMALL
count=0
score=0
thicc=2
rpred=[99]
lpred=[99]
while(True):
    ret, frame = cap.read()
    height,width = frame.shape[:2]
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    faces = face.detectMultiScale(gray,minNeighbors=5,scaleFactor=1.1,minSize=(25,25))
    left_eye = leye.detectMultiScale(gray)
    right_eye = reye.detectMultiScale(gray)
    cv2.rectangle(frame, (0,height-50) , (200,height) , (0,0,0) , thickness=cv2.FILLED )
    for (x,y,w,h) in faces:
        cv2.rectangle(frame, (x,y) , (x+w,y+h) , (100,100,100) , 1 )
    for (x,y,w,h) in right_eye:
        r_eye=frame[y:y+h,x:x+w]
        count=count+1
        r_eye = cv2.cvtColor(r_eye,cv2.COLOR_BGR2GRAY)
        r_eye = cv2.resize(r_eye,(24,24))
        r_eye= r_eye/255
        r_eye= r_eye.reshape(24,24,-1)
        r_eye = np.expand_dims(r_eye,axis=0)
        rpred = model.predict_classes(r_eye)
        if(rpred[0]==1):
            lbl='Open'
        if(rpred[0]==0):
            lbl='Closed'
        break
    for (x,y,w,h) in left_eye:
        l_eye=frame[y:y+h,x:x+w]
        count=count+1
        l_eye = cv2.cvtColor(l_eye,cv2.COLOR_BGR2GRAY)
        l_eye = cv2.resize(l_eye,(24,24))
        l_eye= l_eye/255
        l_eye=l_eye.reshape(24,24,-1)
        l_eye = np.expand_dims(l_eye,axis=0)
        lpred = model.predict_classes(l_eye)
        if(lpred[0]==1):
            lbl='Open'
        if(lpred[0]==0):
            lbl='Closed'
        break
    if(rpred[0]==0 and lpred[0]==0):
        score=score+1
        cv2.putText(frame,"Closed",(10,height-20), font, 1,(255,255,255),1,cv2.LINE_AA)
    # if(rpred[0]==1 or lpred[0]==1):
    else:
        score=score-1
        cv2.putText(frame,"Open",(10,height-20), font, 1,(255,255,255),1,cv2.LINE_AA)
    if(score<0):
        score=0
    cv2.putText(frame,'Score:'+str(score),(100,height-20), font, 1,(255,255,255),1,cv2.LINE_AA)
    if(score>15):
        # 该人感到困倦,我们发出警报声
        cv2.imwrite(os.path.join(path,'image.jpg'),frame)
        try:
            sound.play()
        except: # isplaying = False
            pass
        if(thicc<16):
            thicc= thicc+2
        else:
            thicc=thicc-2
            if(thicc<2):
                thicc=2
        cv2.rectangle(frame,(0,0),(width,height),(0,0,255),thicc)
    cv2.imshow('frame',frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()

司机疲劳检测系统执行
现在让我们执行司机疲劳检测系统,并看看我们 ML 项目的工作情况。要开始项目,您需要打开命令提示符,进入“drowsiness detection.py”主要文件所在的目录。使用以下命令运行脚本。

python “drowsiness detection.py”

打开摄像头和开始检测可能需要几秒钟的时间。

示例截图:

  • 运行疲劳检测程序 - 带有源代码的 Python 项目
    在这里插入图片描述

  • 训练新手的闭眼检测 Python 项目
    在这里插入图片描述

  • 初学者 Python 开源项目的睁眼检测
    在这里插入图片描述

  • 带有警报的 Python 开源项目
    在这里插入图片描述

总结
在这个 Python 项目中,我们构建了一个可以以多种方式实施的疲劳驾驶警报系统。我们使用 OpenCV 通过 Haar 级联分类器检测人脸和眼睛,然后使用 CNN 模型预测状态。

参考资料

  1. Haar 级联分类器介绍
  2. 卷积神经网络基础
  3. 如何使用 OpenCV 进行面部检测
  4. Python 用于图像处理的教程
  5. 使用 Keras 构建深度学习模型的指南
  6. 理解 Softmax 激活函数
  7. Pygame 的简介与使用
  8. 实时视频处理中的 OpenCV 用法
  9. 在汽车中实现疲劳检测的技术探讨
  10. 机器学习在疲劳检测中的应用研究
  11. 用于检测驾驶员疲劳的深度学习模型详解

参考链接:https://data-flair.training/blogs/python-project-driver-drowsiness-detection-system/

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

5 分钟复刻你的声音,一键实现 GPT-Sovits 模型部署

想象一下&#xff0c;只需简单几步操作&#xff0c;就能生成逼真的语音效果&#xff0c;无论是为客户服务还是为游戏角色配音&#xff0c;都能轻松实现。GPT-Sovits 模型&#xff0c;其高效的语音生成能力为实现自然、流畅的语音交互提供了强有力的技术支持。本文将详细介绍如何…

自动化办公|xlwings简介

xlwings 是一个开源的 Python 库&#xff0c;旨在实现 Python 与 Microsoft Excel 的无缝集成。它允许用户使用 Python 脚本自动化 Excel 操作&#xff0c;读取和写入数据&#xff0c;执行宏&#xff0c;甚至调用 VBA 脚本。这使得数据分析、报告生成和其他与 Excel 相关的任务…

JTAG调试器的使用方法

概述: JTAG(联合测试行动组)是基于IEEE 1149.1标准的专用硬件接口。该接口旨在将复杂的芯片和设备连接到标准测试和调试硬件。目前JTAG主要用于: Output control of microcircuits; Testing of printed circuit boards; Flashing of microchips with memory; Chip softwa…

第三次作业:源码编译安装httpd 2.4,提供系统服务管理脚本并测试(两种方法实现)

准备工作 下载httpd软件包进行源码安装 [rootrocky ~]# wget https://archive.apache.org/dist/httpd/httpd-2.4.46.tar.gz 由于进行源码安装&#xff0c;需要对安装对应的编译工具 [rootopen2 ~]# yum install gcc gcc-c make -y 解压文件到指定的目录/usr/local/src下 [root…

Web自动化之验证码识别彻底解决方案

验证码识别解决方案 对于web应用程序来讲&#xff0c;处于安全性考虑&#xff0c;在登录的时候&#xff0c;都会设置验证码&#xff0c;验证码的类型种类繁多&#xff0c;有图片中辨别数字字母的&#xff0c;有点击图片中指定的文字的&#xff0c;也有算术计算结果的&#xff…

第34天:Web开发-PHP应用鉴别修复AI算法流量检测PHP.INI通用过滤内置函数

#知识点 1、安全开发-原生PHP-PHP.INI安全 2、安全开发-原生PHP-全局文件&单函数 3、安全开发-原生PHP-流量检测&AI算法 一、通用-PHP.INI设置 参考&#xff1a; https://www.yisu.com/ask/28100386.html https://blog.csdn.net/u014265398/article/details/109700309 …

C++多态的认识与理解

多态的定义 多态其实就是同一操作在不同的对象上可以有不同的实现方式。 多态的类型 多态分为静态多态和动态多态两种&#xff0c;而静态多态其实我们之前就了解过&#xff0c;今天主要是讲解一下动态多态。 静态多态&#xff08;编译时多态&#xff09;:静态多态其实就是在…

Ubuntu安装搜狗输入法

Ubuntu安装搜狗输入法 官网完整安装步骤调整默认输入法 官网 搜狗输入法 - 官网&#xff1a;https://shurufa.sogou.com/ 搜狗输入法Linux版 - 首页&#xff1a;https://shurufa.sogou.com/linux 搜狗输入法Linux版 - 安装指南&#xff1a;https://shurufa.sogou.com/linux/gu…

ElasticSearch下

DSL查询 叶子查询&#xff1a;在特定字段里查询特定值&#xff0c;属于简单查询&#xff0c;很少单独使用复合查询&#xff1a;以逻辑方式组合多个叶子查询或更改叶子查询的行为方式 在查询后还可以对查询结果做处理&#xff1a; 排序&#xff1a;按照1个或多个字段做排序分页…

【个人开发】nginx域名映射及ssl证书配置踩坑记录

1. 背景 买了个域名&#xff0c;申请了ssl证书&#xff0c;买都买了&#xff0c;不得部署点东西。于是开始一堆踩坑之旅。 2. 踩过的坑 2.1 报错1:域名访问 Invalid Host header 项目是一个简单的vue项目&#xff0c;启动方式如下 npm run serve但浏览器出现报错&#xff…

Go-Zero整合Goose实现MySQL数据库版本管理

推荐阅读 【系列好文】go-zero从入门到精通&#xff08;看了就会&#xff09; 教程地址&#xff1a;https://blog.csdn.net/u011019141/article/details/139619172 Go-Zero整合Goose实现MySQL数据库版本管理的教程 在开发中&#xff0c;数据库迁移和版本管理是必不可少的工作。…

每日一题洛谷P1427 小鱼的数字游戏c++

#include<iostream> using namespace std; int main() {long long s[100] { 0 };int i 0;while (1) {cin >> s[i];if (s[i]0) {break;}i;}for (i; i > 0;i--) {if(s[i]!0)cout << s[i] << " ";}return 0; }

力扣 子集

回溯基础&#xff0c;一题多解&#xff0c;不同的回朔过程。 题目 求子集中&#xff0c;数组的每种元素有选与不选两种状态。因此在使用dfs与回溯时把每一个元素分别进行选与不选的情况考虑即可。可以先用dfs跳过当前元素即不选然后一直深层挖下去&#xff0c;直到挖到最深了即…

宇泰串口卡驱动在Ubuntu22.04编译、安装汇总

从官网下载驱动官网地址 上传到Ubuntu, 目录结构如下&#xff1a; 驱动源代码: 驱动代码是基于开源项目编译来的 编译路径不能有中文路径&#xff0c;否则可能有类似错误 源码是基于Linux2.3内核编译&#xff0c;我当前是6.8.0-51&#xff0c;数据结构有升级&#xff0c;需要调…

LSA更新、撤销

LSA的新旧判断&#xff1a; 1.seq&#xff0c;值越大越优先 2.chksum&#xff0c;值越大越优先 3.age&#xff0c;本地的LSA age和收到的LSA age作比较 如果差值<900s&#xff0c;认为age一致&#xff0c;保留本地的&#xff1a;我本地有一条LSA是100 你给的是400 差值小于…

运行fastGPT 第四步 配置ONE API 添加模型

上次已经装好了所有的依赖和程序。 下面在网页中配置One API &#xff0c;这个是大模型的接口。配置好了之后&#xff0c;就可以配置fastGPT了。 打开 OneAPI 页面 添加模型 这里要添加具体的付费模型的API接口填进来。 可以通过ip:3001访问OneAPI后台&#xff0c;**默认账号…

强化学习-蒙特卡洛方法

强化学习-数学理论 强化学习-基本概念强化学习-贝尔曼公式强化学习-贝尔曼最优公式强化学习-值迭代与策略迭代强化学习-蒙特卡洛方法 文章目录 强化学习-数学理论一、蒙特卡洛方法理论(Monte Carlo, MC)二、MC Basic2.1 算法拆解2.2 MC Basic算法 三、MC Exploring Starts3.1 …

【专题一 递归】21. 合并两个有序链表

1.题目解析 2.讲解算法原理 解法:递归-> 重复的子问题 重复子问题 ->函数头的设计 合并两个有序链表--->Node dfs(l1&#xff0c;l2) 只关心某一个子问题在做什么事情 ->函数体的设计 比大小l1→next dfs( l1.next, l2)return l1 递归的出口 if(l1null)return l2…

企业级NoSQL数据库Redis

1.浏览器缓存过期机制 1.1 最后修改时间 last-modified 浏览器缓存机制是优化网页加载速度和减少服务器负载的重要手段。以下是关于浏览器缓存过期机制、Last-Modified 和 ETag 的详细讲解: 一、Last-Modified 头部 定义:Last-Modified 表示服务器上资源的最后修改时间。 作…

FPGA车牌识别

基于FPGA的车牌识别主要包含以下几个步骤&#xff1a;图像采集、颜色空间转换、边缘检测、形态学处理&#xff08;腐蚀和膨胀&#xff09;、特征值提取、模板匹配、结果显示。先用matlab对原理进行仿真&#xff0c;后用vivado和modelsim进行设计和仿真。 一、1.图像采集采用ov…