卡车司机在白天和晚上长途运输货物和重物,他们经常遭受睡眠不足的困扰。疲劳和困倦是高速公路上发生重大事故的一些主要原因。汽车行业正在研究一些可以检测困倦并提醒驾驶员注意的技术。
在这个项目中,我们将使用 Raspberry Pi、OpenCV 和 Pi 摄像头模块为驾驶员构建睡眠感应和警报系统。该系统的基本目的是跟踪驾驶员的面部状况和眼球运动,如果驾驶员感到困倦,则系统将触发警告信息。这是我们之前人脸地标检测和人脸识别应用的扩展。
所需组件
硬件组件
树莓派 3
Pi 相机模块
微型 USB 数据线
蜂鸣器
软件和在线服务
开放式CV
数据库
在继续这个 驱动程序嗜睡检测项目之前, 首先我们需要在这个项目中安装 OpenCV、imutils、dlib、Numpy 和一些其他依赖项。OpenCV在这里用于 数字图像处理。数字图像处理最常见的应用是 物体检测、 人脸识别和 人数统计。
这里我们只使用树莓派、Pi Camera 和蜂鸣器来构建这个睡眠检测系统。
在树莓派中安装 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 时,它会触发警报,提醒您有关情况。
导入人脸识别
导入简历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()
评论
查看更多