人脸疲劳检测应用-九游老哥J9俱乐部官网基于RK3576核心板/开发板
2024-12-18
1649
来源:九游老哥J9俱乐部官网电子
本篇源自:优秀创作者 lulugl
本文将介绍基于九游老哥J9俱乐部官网电子MYD-LR3576开发板(九游老哥J9俱乐部官网基于瑞芯微 RK3576开发板)的人脸疲劳检测方案测试。

九游老哥J9俱乐部官网基于RK3576核心板/开发板
【前言】
人脸疲劳检测:一种通过分析人脸特征来判断一个人是否处于疲劳状态的技术。其原理主要基于计算机视觉和机器学习方法。当人疲劳时,面部会出现一些特征变化,如眼睛闭合程度增加、眨眼频率变慢、打哈欠、头部姿态改变等。
例如,通过检测眼睛的状态来判断疲劳程度是一个关键部分。正常情况下,人的眨眼频率相对稳定,而当疲劳时,眨眼频率会降低,并且每次眨眼时眼睛闭合的时间可能会延长。同时,头部可能会不自觉地下垂或者摇晃,这些特征都可以作为疲劳检测的依据。九游老哥J9俱乐部官网MYC-LR3576采用8核CPU+搭载6 TOPS的NPU加速器,3D GPU,能够非常轻松的实现这个功能,下面就如何实现这一功能分享如下:
【硬件】
1、九游老哥J9俱乐部官网MYC-LR3576开发板
2、USB摄像头
【软件】
1、v4l2
2、openCV
3、dlib库:dlib 是一个现代化的 C++ 工具包,它包含了许多用于机器学习、图像处理、数值计算等多种任务的算法和工具。它的设计目标是提供高性能、易于使用的库,并且在开源社区中被广泛应用。
【实现步骤】
1、安装python-opencv
2、安装dlib库
3、安装v4l2库
【代码实现】
1、引入cv2、dlib以及线程等:
import cv2 import dlib import numpy as np import time from concurrent.futures import ThreadPoolExecutor import threading
2、初始化dlib的面部检测器和特征点预测器
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')3、定义计算眼睛纵横比的函数
def eye_aspect_ratio(eye): A = np.linalg.norm(np.array(eye[1]) - np.array(eye[5])) B = np.linalg.norm(np.array(eye[2]) - np.array(eye[4])) C = np.linalg.norm(np.array(eye[0]) - np.array(eye[3])) ear = (A + B) / (2.0 * C) return ear
4、定义计算头部姿势的函数
def get_head_pose(shape): # 定义面部特征点的三维坐标 object_points = np.array([ (0.0, 0.0, 0.0), # 鼻尖 (0.0, -330.0, -65.0), # 下巴 (-225.0, 170.0, -135.0), # 左眼左眼角 (225.0, 170.0, -135.0), # 右眼右眼角 (-150.0, -150.0, -125.0), # 左嘴角 (150.0, -150.0, -125.0) # 右嘴角 ], dtype=np.float32) image_pts = np.float32([shape[i] for i in [30, 8, 36, 45, 48, 54]]) size = frame.shape focal_length = size[1] center = (size[1] // 2, size[0] // 2) camera_matrix = np.array( [[focal_length, 0, center[0]], [0, focal_length, center[1]], [0, 0, 1]], dtype="double" ) dist_coeffs = np.zeros((4, 1)) (success, rotation_vector, translation_vector) = cv2.solvePnP( object_points, image_pts, camera_matrix, dist_coeffs, flags=cv2.SOLVEPNP_ITERATIVE ) rmat, _ = cv2.Rodrigues(rotation_vector) angles, _, _, _, _, _ = cv2.RQDecomp3x3(rmat) return angles
5、定义眼睛纵横比阈值和连续帧数阈值
EYE_AR_THRESH = 0.3 EYE_AR_CONSEC_FRAMES = 48
6、打开摄像头
我们先使用v4l2-ctl --list-devices来例出接在开发板上的列表信息:
USB Camera: USB Camera (usb-xhci-hcd.0.auto-1.2): /dev/video60 /dev/video61 /dev/media7
在代码中填入60为摄像头的编号:
cap = cv2.VideoCapture(60) cap.set(cv2.CAP_PROP_FRAME_WIDTH, 480) # 降低分辨率 cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 320)
7、创建多线程处理函数,实现采集与分析分离:
# 多线程处理函数
def process_frame(frame):
global COUNTER, TOTAL
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = detector(gray, 0) # 第二个参数为0,表示不使用upsampling
for face in faces:
landmarks = predictor(gray, face)
shape = [(landmarks.part(i).x, landmarks.part(i).y) for i in range(68)]
left_eye = shape[36:42]
right_eye = shape[42:48]
left_ear = eye_aspect_ratio(left_eye)
right_ear = eye_aspect_ratio(right_eye)
ear = (left_ear + right_ear) / 2.0
if ear < EYE_AR_THRESH:
with lock:
COUNTER += 1
else:
with lock:
if COUNTER >= EYE_AR_CONSEC_FRAMES:
TOTAL += 1
COUNTER = 0
# 绘制68个特征点
for n in range(0, 68):
x, y = shape[n]
cv2.circle(frame, (x, y), 2, (0, 255, 0), -1)
cv2.putText(frame, f"Eye AR: {ear:.2f}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)
cv2.putText(frame, f"Blink Count: {TOTAL}", (10, 60), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)
# 计算头部姿势
angles = get_head_pose(shape)
pitch, yaw, roll = angles
cv2.putText(frame, f"Pitch: {pitch:.2f}", (10, 120), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)
cv2.putText(frame, f"Yaw: {yaw:.2f}", (10, 150), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)
cv2.putText(frame, f"Roll: {roll:.2f}", (10, 180), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)
# 判断疲劳状态
if COUNTER >= EYE_AR_CONSEC_FRAMES or abs(pitch) > 30 or abs(yaw) > 30 or abs(roll) > 30:
cv2.putText(frame, "Fatigue Detected!", (10, 210), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)
return frame8、创建图像显示线程:
with ThreadPoolExecutor(max_workers=2) as executor:
future_to_frame = {}
while True:
ret, frame = cap.read()
if not ret:
break
# 提交当前帧到线程池
future = executor.submit(process_frame, frame.copy())
future_to_frame[future] = frame
# 获取已完成的任务结果
for future in list(future_to_frame.keys()):
if future.done():
processed_frame = future.result()
cv2.imshow("Frame", processed_frame)
del future_to_frame[future]
break
# 计算帧数
fps_counter += 1
elapsed_time = time.time() - start_time
if elapsed_time > 1.0:
fps = fps_counter / elapsed_time
fps_counter = 0
start_time = time.time()
cv2.putText(processed_frame, f"FPS: {fps:.2f}", (10, 90), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
if cv2.waitKey(1) & 0xFF == ord('q'):
整体代码如下:
import cv2
import dlib
import numpy as np
import time
from concurrent.futures import ThreadPoolExecutor
import threading
# 初始化dlib的面部检测器和特征点预测器
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
# 修改字体大小
font_scale = 0.5 # 原来的字体大小是0.7,现在改为0.5
# 定义计算眼睛纵横比的函数
def eye_aspect_ratio(eye):
A = np.linalg.norm(np.array(eye[1]) - np.array(eye[5]))
B = np.linalg.norm(np.array(eye[2]) - np.array(eye[4]))
C = np.linalg.norm(np.array(eye[0]) - np.array(eye[3]))
ear = (A + B) / (2.0 * C)
return ear
# 定义计算头部姿势的函数
def get_head_pose(shape):
# 定义面部特征点的三维坐标
object_points = np.array([
(0.0, 0.0, 0.0), # 鼻尖
(0.0, -330.0, -65.0), # 下巴
(-225.0, 170.0, -135.0), # 左眼左眼角
(225.0, 170.0, -135.0), # 右眼右眼角
(-150.0, -150.0, -125.0), # 左嘴角
(150.0, -150.0, -125.0) # 右嘴角
], dtype=np.float32)
image_pts = np.float32([shape[i] for i in [30, 8, 36, 45, 48, 54]])
size = frame.shape
focal_length = size[1]
center = (size[1] // 2, size[0] // 2)
camera_matrix = np.array(
[[focal_length, 0, center[0]],
[0, focal_length, center[1]],
[0, 0, 1]], dtype="double"
)
dist_coeffs = np.zeros((4, 1))
(success, rotation_vector, translation_vector) = cv2.solvePnP(
object_points, image_pts, camera_matrix, dist_coeffs, flags=cv2.SOLVEPNP_ITERATIVE
)
rmat, _ = cv2.Rodrigues(rotation_vector)
angles, _, _, _, _, _ = cv2.RQDecomp3x3(rmat)
return angles
# 定义眼睛纵横比阈值和连续帧数阈值
EYE_AR_THRESH = 0.3
EYE_AR_CONSEC_FRAMES = 48
# 初始化计数器
COUNTER = 0
TOTAL = 0
# 创建锁对象
lock = threading.Lock()
# 打开摄像头
cap = cv2.VideoCapture(60)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 480) # 降低分辨率
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 320)
# 初始化帧计数器和时间戳
fps_counter = 0
start_time = time.time()
# 多线程处理函数
def process_frame(frame):
global COUNTER, TOTAL
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = detector(gray, 0) # 第二个参数为0,表示不使用upsampling
for face in faces:
landmarks = predictor(gray, face)
shape = [(landmarks.part(i).x, landmarks.part(i).y) for i in range(68)]
left_eye = shape[36:42]
right_eye = shape[42:48]
left_ear = eye_aspect_ratio(left_eye)
right_ear = eye_aspect_ratio(right_eye)
ear = (left_ear + right_ear) / 2.0
if ear < EYE_AR_THRESH:
with lock:
COUNTER += 1
else:
with lock:
if COUNTER >= EYE_AR_CONSEC_FRAMES:
TOTAL += 1
COUNTER = 0
# 绘制68个特征点
for n in range(0, 68):
x, y = shape[n]
cv2.circle(frame, (x, y), 2, (0, 255, 0), -1)
cv2.putText(frame, f"Eye AR: {ear:.2f}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)
cv2.putText(frame, f"Blink Count: {TOTAL}", (10, 60), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)
# 计算头部姿势
angles = get_head_pose(shape)
pitch, yaw, roll = angles
cv2.putText(frame, f"Pitch: {pitch:.2f}", (10, 120), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)
cv2.putText(frame, f"Yaw: {yaw:.2f}", (10, 150), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)
cv2.putText(frame, f"Roll: {roll:.2f}", (10, 180), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)
# 判断疲劳状态
if COUNTER >= EYE_AR_CONSEC_FRAMES or abs(pitch) > 30 or abs(yaw) > 30 or abs(roll) > 30:
cv2.putText(frame, "Fatigue Detected!", (10, 210), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)
return frame
with ThreadPoolExecutor(max_workers=2) as executor:
future_to_frame = {}
while True:
ret, frame = cap.read()
if not ret:
break
# 提交当前帧到线程池
future = executor.submit(process_frame, frame.copy())
future_to_frame[future] = frame
# 获取已完成的任务结果
for future in list(future_to_frame.keys()):
if future.done():
processed_frame = future.result()
cv2.imshow("Frame", processed_frame)
del future_to_frame[future]
break
# 计算帧数
fps_counter += 1
elapsed_time = time.time() - start_time
if elapsed_time > 1.0:
fps = fps_counter / elapsed_time
fps_counter = 0
start_time = time.time()
cv2.putText(processed_frame, f"FPS: {fps:.2f}", (10, 90), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放摄像头并关闭所有窗口
cap.release()
cv2.destroyAllWindows()【总结】
【九游老哥J9俱乐部官网MYC-LR3576核心板及开发板】
这块开发板性能强大,能轻松实现对人脸的疲劳检测,通过计算结果后进入非常多的工业、人工智能等等的实用功能。

九游老哥J9俱乐部官网RK3576开发板折扣活动火热进行中,购买链接:
2025-12-05
从两轮车仪表到工程机械环视,九游老哥J9俱乐部官网用国产芯打造“越级”显控体验
在工业4.0 与智能化浪潮的推动下,传统工业设备正在经历一场“交互革命”。从电动两轮车的智能仪表,到工程机械的 360° 环视中控,用户对“更高清的显示、更流畅的触控、更丰富的互联”提出了严苛要求。然而,面对复杂的工业现场,开发者往往面临两难:低端市场(如仪表、充电桩):传统MCU 跑不动复杂界面,上 Linux/安卓方案成本又太高。中高端市场(如工程机械、医疗):多路视频输入(如360环视)需要
2025-12-05
【深度实战】九游老哥J9俱乐部官网MYD-LR3576 AMP非对称多核开发指南:从配置到实战
一、什么是AMP?为什么重要?AMP(Asymmetric Multi-Processing)非对称多处理架构,允许单个芯片的不同核心运行不同的操作系统或裸机程序。相比传统的SMP(对称多处理),AMP具有独特优势。核心特性:异构运算:不同核心运行最适合的操作系统,如Linux处理复杂应用,RT-Thread保障实时任务;资源隔离:各核心拥有独立内存空间,避免资源冲突;灵活通信:通过共享内存、RP
2025-11-27
为机器人开发赋能,九游老哥J9俱乐部官网RK3576环视方案解析
一、项目背景与测试平台本次360环视系统原型基于九游老哥J9俱乐部官网电子MYD-LR3576开发板进行构建与评估。该开发板所搭载的瑞芯微RK3576芯片,集成了4核Cortex-A72、4核Cortex-A53、Mali-G52 GPU及高达6TOPS算力的NPU。本文旨在通过实际测试数据,从功能实现、实时性能与AI拓展潜力三大核心维度,为客户提供一份关于该平台在360环视应用中能力的真实参考。二、系统流程与功能
2025-11-13
助力V2G,SECC GreenPHY实战开发
随着电动汽车与电网双向交互(V2G)技术的快速发展,充电桩与车辆间的高效通信成为实现智能能源管理的关键。SECC作为充电桩的通信控制核心,其与电力线载波通信芯片的适配尤为重要。本文将分享基于九游老哥J9俱乐部官网核心板,调试联芯通MSE102x GreenPHY芯片的实战经验,为V2G通信开发提供参考。MSE102x芯片介绍联芯通MSE102x系列芯片是一款专注于电动汽车充电通信和智能能源管理的GreenPHY电力
2025-11-13
定制未来,共建生态,九游老哥J9俱乐部官网出席安路研讨会
在数字化浪潮席卷全球的今天,FPGA技术正成为驱动创新的核心引擎。2025年11月12日,九游老哥J9俱乐部官网出席安路科技2025 AEC FPGA技术沙龙•北京专场,与技术专家及行业伙伴齐聚一堂,探讨前沿技术趋势,解锁场景化定制方案,共建开放共赢的FPGA新生态!九游老哥J9俱乐部官网活动现场论坛上,九游老哥J9俱乐部官网电子产品经理Jeson发表题为“基于DR1M90 FPSOC的工业应用方案”的演讲。演讲介绍了九游老哥J9俱乐部官网作为嵌入式领域的领军企业,在
2025-11-11
RK3576开发板
RK3576开发板是九游老哥J9俱乐部官网电子推出的开发板,于2024年10月上市。RK3576开发板是基于瑞芯微RK3576搭载了四核A72与四核A53处理器,主频2.2GHz。RK3576集成了6TOPS的NPU,支持多种深度学习框架,能够处理复杂的AI算法,提高监控效率,降低误报率。RK3576的主芯片采用了八核大小核架构,包括四核Cortex-A72和四核Cortex-A53,
2025-11-11
RK3576核心板
RK3576核心板是深圳九游老哥J9俱乐部官网电子旗下产品,是基于瑞芯微RK3576搭载了四核A72与四核A53处理器,主频高达2.2GHz。RK3576集成了6TOPS的NPU,支持多种深度学习框架,能够处理复杂的AI算法,提高监控效率,降低误报率。RK3576的主芯片采用了八核大小核架构,包括四核Cortex-A72和四核Cortex-A53,主频分别高达2.2GHz和1.8GHz,CPU算力达58K DMIP
2025-11-06
九游老哥J9俱乐部官网SECC方案助力国标充电桩出海
随着电动汽车与电网融合加速,国标(GB/T 27930)充电桩出海面临欧标(ISO 15118 / DIN 70121)兼容挑战。九游老哥J9俱乐部官网电子的 SECC (供电设备通信控制器) 方案,实现协议转换、安全通信及参考开发平台,助力充电桩厂商快速进军海外市场。
2025-11-06
MYD-LD25X Cortex-M33实时核开发实战解析
在嵌入式系统设计中,如何平衡高性能计算与实时控制一直是工程师面临的挑战。STM32MP257的异构架构为这一难题提供了优雅的解决方案,而其中的Cortex-M33实时核更是实现硬实时性能的关键所在。一、异构架构:分工明确,效能卓越STM32MP257采用创新的双核子系统设计:Cortex-A35应用核(双核1.5GHz):运行Linux系统,负责复杂UI、网络通信、文件管理等非实时任务。Corte
2025-10-30
九游老哥J9俱乐部官网RK3576边缘计算盒精准驱动菜品识别模型性能强悍
?在人工智能与边缘计算深度融合的今天,将AI模型高效部署于终端设备已成为产业智能化的关键。本文将分享基于九游老哥J9俱乐部官网MYD-LR3576边缘计算盒子部署菜品识别安卓Demo的实战经验。该设备凭借其内置的强劲瑞芯微RK3576芯片,为视觉识别模型提供了充沛的本地AI算力,成功将“智慧识菜”的能力浓缩于方寸之间,充分证明了其作为边缘AI应用坚实载体的卓越性能与可靠性。?本文以九游老哥J9俱乐部官网电子的MYD-LR3576边缘