如何使用OpenCV和Raspberry Pi构建睡眠感应和警报系统

安全设备/系统

156人已加入

描述

  卡车司机在白天和晚上长途运输货物和重物,他们经常遭受睡眠不足的困扰。疲劳和困倦是高速公路上发生重大事故的一些主要原因。汽车行业正在研究一些可以检测困倦并提醒驾驶员注意的技术。

  在这个项目中,我们将使用 Raspberry Pi、OpenCV 和 Pi 摄像头模块为驾驶员构建睡眠感应和警报系统。该系统的基本目的是跟踪驾驶员的面部状况和眼球运动,如果驾驶员感到困倦,则系统将触发警告信息。这是我们之前人脸地标检测和人脸识别应用的扩展。

  所需组件

  硬件组件

  树莓派 3

  Pi 相机模块

  微型 USB 数据线

  蜂鸣器

  软件和在线服务

  开放式CV

  数据库

  Python3

  在继续这个 驱动程序嗜睡检测项目之前, 首先我们需要在这个项目中安装 OpenCV、imutils、dlib、Numpy 和一些其他依赖项。OpenCV在这里用于 数字图像处理。数字图像处理最常见的应用是 物体检测、 人脸识别和 人数统计。

  这里我们只使用树莓派、Pi Camera 和蜂鸣器来构建这个睡眠检测系统。

OpenCV

在树莓派中安装 OpenCV

在安装 OpenCV 和其他依赖项之前,Raspberry Pi 需要完全更新。使用以下命令将 Raspberry Pi 更新到其最新版本:

 

sudo apt-get 更新

 

然后使用以下命令安装在 Raspberry Pi 上安装 OpenCV 所需的依赖项。

 

sudo apt-get install libhdf5-dev -y 
sudo apt-get install libhdf5-serial-dev –y 
sudo apt-get install libatlas-base-dev –y 
sudo apt-get install libjasper-dev -y 
sudo apt-get install libqtgui4 –y 
sudo apt-get install libqt4-test –y

 

最后,使用以下命令在 Raspberry Pi 上安装 OpenCV。

 

pip3 安装 opencv-contrib-python==4.1.0.25

 

安装其他必需的软件包

在对 Raspberry Pi 进行嗜睡检测器编程之前,让我们安装其他所需的软件包。

安装 dlib: dlib 是现代工具包,其中包含用于解决实际问题的机器学习算法和工具。使用以下命令安装 dlib。

 

pip3 安装 dlib

 

安装 NumPy: NumPy 是科学计算的核心库,包含强大的 n 维数组对象,提供集成 C、C++ 等的工具。

 

pip3 安装 numpy

 

安装 face_recognition 模块:该库用于从 Python 或命令行识别和操作人脸。使用以下命令安装人脸识别库。

 

Pip3 安装 face_recognition

 

最后,使用以下命令安装eye_game库:

 

pip3 安装眼睛游戏

 

对树莓派进行编程

使用 OpenCV 的 Driver Drrowsiness Detector的完整代码在页面末尾给出。在这里,我们将解释代码的一些重要部分,以便更好地理解。

因此,像往常一样,通过包含所有必需的库来启动代码。

 

导入人脸识别
导入简历2
将 numpy 导入为 np
进口时间
导入简历2
导入 RPi.GPIO 作为 GPIO
导入 eye_game

 

之后,创建一个实例以从 pi 相机获取视频源。如果您使用多个摄像头,则在cv2.VideoCapture(0)函数中将零替换为一个。

 

video_capture = cv2.VideoCapture(0)

 

现在在接下来的几行中,输入文件的文件名和路径。就我而言,代码和文件都在同一个文件夹中。然后使用人脸编码得到图片中的人脸位置。

 

img_image = face_recognition.load_image_file("img.jpg")
img_face_encoding = face_recognition.face_encodings(img_image)[0]

 

之后创建两个数组来保存人脸及其名称。我只使用一张图片;您可以在代码中添加更多图像及其路径。

 

known_face_encodings = [
    img_face_encoding ]
known_face_names = [
    “阿什”
]

 

然后创建一些变量来存储面部部位的位置、面部名称和编码。

 

face_locations = []
face_encodings = []
面名 = []
process_this_frame = True

 

在while函数中,从流中捕获视频帧并将帧调整为更小的尺寸,并将捕获的帧转换为 RGB 颜色以进行人脸识别。

 

ret, frame = video_capture.read()
 small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
 rgb_small_frame = small_frame[:, :, ::-1]

 

之后,运行人脸识别过程,将视频中的人脸与图像进行比较。并获得面部部位的位置。

 

如果 process_this_frame:
        face_locations = face_recognition.face_locations(rgb_small_frame)
        face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)
        cv2.imwrite(文件,small_frame)

 

如果识别出的人脸与图像中的人脸匹配,则调用eyegame函数跟踪眼球运动。代码会反复跟踪眼球和眼球的位置。 

 

face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
            best_match_index = np.argmin(face_distances)
            如果匹配[best_match_index]:
                名称 = known_face_names[best_match_index]
                方向= eye_game.get_eyeball_direction(文件)
                打印(方向)

 

如果代码在 10 秒内没有检测到任何眼球运动,则会触发警报将人叫醒。

 

别的:
                    计数=1+计数
                    打印(计数)
                    如果(计数>=10):
                       GPIO.输出(蜂鸣器,GPIO.HIGH)
                       时间.sleep(2)
                       GPIO.输出(蜂鸣器,GPIO.LOW)
                       打印(“警报!警报!检测到驾驶员嗜睡”)

 

然后使用 OpenCV 函数在面部周围绘制一个矩形并在其上放置文本。此外,使用cv2.imshow函数显示视频帧。

 

cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2)
 cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 255, 0), cv2.FILLED)
 字体 = cv2.FONT_HERSHEY_DUPLEX
 cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (0, 0, 255), 1)
 cv2.imshow('视频', 帧)
设置键“S”以停止代码。
如果 cv2.waitKey(1) & 0xFF == ord('s'):
        休息

 

  测试驾驶员困倦检测系统

  代码准备好后,将 Pi 摄像头和蜂鸣器连接到Raspberry Pi并运行代码。大约 10 秒后,将出现一个窗口,其中包含来自您的 Raspberry Pi 相机的实时流。当设备识别到人脸时,它会在框架上打印你的名字并开始跟踪眼球运动。现在闭上眼睛 7 到 8 秒来测试警报。当计数超过 10 时,它会触发警报,提醒您有关情况。

OpenCV
 

导入人脸识别
导入简历2
将 numpy 导入为 np
进口时间
导入简历2
导入 eye_game
导入 RPi.GPIO 作为 GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(假)
蜂鸣器= 23
GPIO.setup(蜂鸣器,GPIO.OUT)
以前的 =“未知”
计数=0
video_capture = cv2.VideoCapture(0)
#frame = (video_capture, 文件)
文件 = 'image_data/image.jpg'
# 加载示例图片并学习如何识别它。
img_image = face_recognition.load_image_file("img.jpg")
img_face_encoding = face_recognition.face_encodings(img_image)[0]
# 创建已知人脸编码及其名称的数组
known_face_encodings = [
img_face_encoding
]

known_face_names = [
“阿什”
]

# 初始化一些变量
face_locations = []
face_encodings = []
面名 = []
process_this_frame = True
而真:
# 抓取单帧视频
ret, frame = video_capture.read()
# 将视频帧大小调整为 1/4 大小,以加快人脸识别处理
small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
# 将图像从 BGR 颜色(OpenCV 使用)转换为 RGB 颜色(face_recognition 使用)
rgb_small_frame = small_frame[:, :, ::-1]
# 只处理每隔一帧的视频以节省时间
如果 process_this_frame:
# 查找当前视频帧中的所有人脸和人脸编码
face_locations = face_recognition.face_locations(rgb_small_frame)
face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)
cv2.imwrite(文件,small_frame)
面名 = []
对于 face_encodings 中的 face_encoding:
# 查看人脸是否与已知人脸匹配
匹配 = face_recognition.compare_faces(known_face_encodings, face_encoding)
名称=“未知”
face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
best_match_index = np.argmin(face_distances)
如果匹配[best_match_index]:
名称 = known_face_names[best_match_index]
方向= eye_game.get_eyeball_direction(文件)
打印(方向)
#eye_game.api.get_eyeball_direction(cv_image_array)
如果前一个!=方向:
上一个=方向
别的:
print("老一样")
计数=1+计数
打印(计数)
如果(计数>=10):
GPIO.输出(蜂鸣器,GPIO.HIGH)
时间.sleep(2)
GPIO.输出(蜂鸣器,GPIO.LOW)
打印(“警报!警报!检测到驾驶员嗜睡”)
cv2.putText(frame, "睡意警报!", (10, 30),

cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
face_names.append(名字)
process_this_frame = 不是 process_this_frame
# 显示结果
对于(上、右、下、左),zip 中的名称(face_locations,face_names):
# 缩放人脸位置,因为我们检测到的帧被缩放到 1/4 大小
顶部 *= 4
对 *= 4
底部 *= 4
左 *= 4
# 在脸部周围画一个框
cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2)
# 在人脸下方绘制一个带有名字的标签
cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
字体 = cv2.FONT_HERSHEY_DUPLEX
cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (0, 0, 255), 1)
#cv2.putText(frame, frame_string, (left + 10, top - 10), font, 1.0, (255, 255, 255), 1)
# 显示结果图像
cv2.imshow('视频', 帧)
# 按键盘上的“q”退出!
如果 cv2.waitKey(1) & 0xFF == ord('q'):
休息
# 释放网络摄像头的句柄
video_capture.release()
cv2.destroyAllWindows()

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分