国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

如何用OpenCV進(jìn)行人臉疲勞檢測(cè)--基于米爾瑞芯微RK3576開發(fā)板

發(fā)布時(shí)間:2024-12-19 11:37    發(fā)布者:swiftman
關(guān)鍵詞: 瑞芯微 , RK3576 , 嵌入式 , OpenCV , 米爾電子 , OpenCV
本篇源自:優(yōu)秀創(chuàng)作者 lulugl

本文將介紹基于米爾電子MYD-LR3576開發(fā)板(米爾基于瑞芯微 RK3576開發(fā)板)的人臉疲勞檢測(cè)方案測(cè)試。
米爾基于RK3576核心板/開發(fā)板
【前言】
人臉疲勞檢測(cè):一種通過分析人臉特征來判斷一個(gè)人是否處于疲勞狀態(tài)的技術(shù)。其原理主要基于計(jì)算機(jī)視覺和機(jī)器學(xué)習(xí)方法。當(dāng)人疲勞時(shí),面部會(huì)出現(xiàn)一些特征變化,如眼睛閉合程度增加、眨眼頻率變慢、打哈欠、頭部姿態(tài)改變等。
例如,通過檢測(cè)眼睛的狀態(tài)來判斷疲勞程度是一個(gè)關(guān)鍵部分。正常情況下,人的眨眼頻率相對(duì)穩(wěn)定,而當(dāng)疲勞時(shí),眨眼頻率會(huì)降低,并且每次眨眼時(shí)眼睛閉合的時(shí)間可能會(huì)延長(zhǎng)。同時(shí),頭部可能會(huì)不自覺地下垂或者搖晃,這些特征都可以作為疲勞檢測(cè)的依據(jù)。米爾MYC-LR3576采用8核CPU+搭載6 TOPS的NPU加速器,3D GPU,能夠非常輕松的實(shí)現(xiàn)這個(gè)功能,下面就如何實(shí)現(xiàn)這一功能分享如下:
【硬件】
1、米爾MYC-LR3576開發(fā)板
2、USB攝像頭
【軟件】
1、v4l2
2、openCV
3、dlib庫(kù):dlib 是一個(gè)現(xiàn)代化的 C++ 工具包,它包含了許多用于機(jī)器學(xué)習(xí)、圖像處理、數(shù)值計(jì)算等多種任務(wù)的算法和工具。它的設(shè)計(jì)目標(biāo)是提供高性能、易于使用的庫(kù),并且在開源社區(qū)中被廣泛應(yīng)用。
【實(shí)現(xiàn)步驟】
1、安裝python-opencv
2、安裝dlib庫(kù)
3、安裝v4l2庫(kù)
代碼實(shí)現(xiàn)】
1、引入cv2、dlib以及線程等:
  1. import cv2
  2. import dlib
  3. import numpy as np
  4. import time
  5. from concurrent.futures import ThreadPoolExecutor
  6. import threading
復(fù)制代碼

2、初始化dlib的面部檢測(cè)器和特征點(diǎn)預(yù)測(cè)器
  1. detector = dlib.get_frontal_face_detector()
  2. predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
復(fù)制代碼

3、定義計(jì)算眼睛縱橫比的函數(shù)
  1. def eye_aspect_ratio(eye):
  2.     A = np.linalg.norm(np.array(eye[1]) - np.array(eye[5]))
  3.     B = np.linalg.norm(np.array(eye[2]) - np.array(eye[4]))
  4.     C = np.linalg.norm(np.array(eye[0]) - np.array(eye[3]))
  5.     ear = (A + B) / (2.0 * C)                                                                                
  6.     return ear
復(fù)制代碼

4、定義計(jì)算頭部姿勢(shì)的函數(shù)
  1. def get_head_pose(shape):
  2.     # 定義面部特征點(diǎn)的三維坐標(biāo)
  3.     object_points = np.array([
  4.         (0.0, 0.0, 0.0),             # 鼻尖
  5.         (0.0, -330.0, -65.0),        # 下巴
  6.         (-225.0, 170.0, -135.0),     # 左眼左眼角
  7.         (225.0, 170.0, -135.0),      # 右眼右眼角
  8.         (-150.0, -150.0, -125.0),    # 左嘴角
  9.         (150.0, -150.0, -125.0)      # 右嘴角
  10.     ], dtype=np.float32)

  11.     image_pts = np.float32([shape[i] for i in [30, 8, 36, 45, 48, 54]])
  12.     size = frame.shape
  13.     focal_length = size[1]
  14.     center = (size[1] // 2, size[0] // 2)
  15.     camera_matrix = np.array(
  16.         [[focal_length, 0, center[0]],
  17.          [0, focal_length, center[1]],
  18.          [0, 0, 1]], dtype="double"
  19.     )

  20.     dist_coeffs = np.zeros((4, 1))
  21.     (success, rotation_vector, translation_vector) = cv2.solvePnP(
  22.         object_points, image_pts, camera_matrix, dist_coeffs, flags=cv2.SOLVEPNP_ITERATIVE
  23.     )

  24.     rmat, _ = cv2.Rodrigues(rotation_vector)
  25.     angles, _, _, _, _, _ = cv2.RQDecomp3x3(rmat)
  26.     return angles
復(fù)制代碼

5、定義眼睛縱橫比閾值和連續(xù)幀數(shù)閾值
  1. EYE_AR_THRESH = 0.3
  2. EYE_AR_CONSEC_FRAMES = 48
復(fù)制代碼

6、打開攝像頭
我們先使用v4l2-ctl --list-devices來例出接在開發(fā)板上的列表信息:
  1. USB Camera: USB Camera (usb-xhci-hcd.0.auto-1.2):
  2.         /dev/video60
  3.         /dev/video61
  4.         /dev/media7
復(fù)制代碼

在代碼中填入60為攝像頭的編號(hào):
  1. cap = cv2.VideoCapture(60)
  2. cap.set(cv2.CAP_PROP_FRAME_WIDTH, 480)  # 降低分辨率
  3. cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 320)
復(fù)制代碼

7、創(chuàng)建多線程處理函數(shù),實(shí)現(xiàn)采集與分析分離:
  1. # 多線程處理函數(shù)
  2. def process_frame(frame):
  3.     global COUNTER, TOTAL
  4.     gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
  5.     faces = detector(gray, 0)  # 第二個(gè)參數(shù)為0,表示不使用upsampling

  6.     for face in faces:
  7.         landmarks = predictor(gray, face)
  8.         shape = [(landmarks.part(i).x, landmarks.part(i).y) for i in range(68)]
  9.         
  10.         left_eye = shape[36:42]
  11.         right_eye = shape[42:48]

  12.         left_ear = eye_aspect_ratio(left_eye)
  13.         right_ear = eye_aspect_ratio(right_eye)
  14.         ear = (left_ear + right_ear) / 2.0

  15.         if ear < EYE_AR_THRESH:
  16.             with lock:
  17.                 COUNTER += 1
  18.         else:
  19.             with lock:
  20.                 if COUNTER >= EYE_AR_CONSEC_FRAMES:
  21.                     TOTAL += 1
  22.                 COUNTER = 0

  23.         # 繪制68個(gè)特征點(diǎn)
  24.         for n in range(0, 68):
  25.             x, y = shape[n]
  26.             cv2.circle(frame, (x, y), 2, (0, 255, 0), -1)

  27.         cv2.putText(frame, f"Eye AR: {ear:.2f}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)
  28.         cv2.putText(frame, f"Blink Count: {TOTAL}", (10, 60), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)

  29.         # 計(jì)算頭部姿勢(shì)
  30.         angles = get_head_pose(shape)
  31.         pitch, yaw, roll = angles
  32.         cv2.putText(frame, f"Pitch: {pitch:.2f}", (10, 120), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)
  33.         cv2.putText(frame, f"Yaw: {yaw:.2f}", (10, 150), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)
  34.         cv2.putText(frame, f"Roll: {roll:.2f}", (10, 180), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)

  35.         # 判斷疲勞狀態(tài)
  36.         if COUNTER >= EYE_AR_CONSEC_FRAMES or abs(pitch) > 30 or abs(yaw) > 30 or abs(roll) > 30:
  37.             cv2.putText(frame, "Fatigue Detected!", (10, 210), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)

  38.     return frame
復(fù)制代碼
8、創(chuàng)建圖像顯示線程:
  1. with ThreadPoolExecutor(max_workers=2) as executor:
  2.     future_to_frame = {}
  3.     while True:
  4.         ret, frame = cap.read()
  5.         if not ret:
  6.             break

  7.         # 提交當(dāng)前幀到線程池
  8.         future = executor.submit(process_frame, frame.copy())
  9.         future_to_frame[future] = frame

  10.         # 獲取已完成的任務(wù)結(jié)果
  11.         for future in list(future_to_frame.keys()):
  12.             if future.done():
  13.                 processed_frame = future.result()
  14.                 cv2.imshow("Frame", processed_frame)
  15.                 del future_to_frame[future]
  16.                 break

  17.         # 計(jì)算幀數(shù)
  18.         fps_counter += 1
  19.         elapsed_time = time.time() - start_time
  20.         if elapsed_time > 1.0:
  21.             fps = fps_counter / elapsed_time
  22.             fps_counter = 0
  23.             start_time = time.time()
  24.             cv2.putText(processed_frame, f"FPS: {fps:.2f}", (10, 90), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)

  25.         if cv2.waitKey(1) & 0xFF == ord('q'):
復(fù)制代碼

實(shí)現(xiàn)效果:

根據(jù)檢測(cè)的結(jié)果,我們就可以來實(shí)現(xiàn)疲勞提醒等等的功能。
整體代碼如下:
  1. import cv2
  2. import dlib
  3. import numpy as np
  4. import time
  5. from concurrent.futures import ThreadPoolExecutor
  6. import threading

  7. # 初始化dlib的面部檢測(cè)器和特征點(diǎn)預(yù)測(cè)器
  8. detector = dlib.get_frontal_face_detector()
  9. predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')

  10. # 修改字體大小
  11. font_scale = 0.5  # 原來的字體大小是0.7,現(xiàn)在改為0.5

  12. # 定義計(jì)算眼睛縱橫比的函數(shù)
  13. def eye_aspect_ratio(eye):
  14.     A = np.linalg.norm(np.array(eye[1]) - np.array(eye[5]))
  15.     B = np.linalg.norm(np.array(eye[2]) - np.array(eye[4]))
  16.     C = np.linalg.norm(np.array(eye[0]) - np.array(eye[3]))
  17.     ear = (A + B) / (2.0 * C)                                                                                
  18.     return ear

  19. # 定義計(jì)算頭部姿勢(shì)的函數(shù)
  20. def get_head_pose(shape):
  21.     # 定義面部特征點(diǎn)的三維坐標(biāo)
  22.     object_points = np.array([
  23.         (0.0, 0.0, 0.0),             # 鼻尖
  24.         (0.0, -330.0, -65.0),        # 下巴
  25.         (-225.0, 170.0, -135.0),     # 左眼左眼角
  26.         (225.0, 170.0, -135.0),      # 右眼右眼角
  27.         (-150.0, -150.0, -125.0),    # 左嘴角
  28.         (150.0, -150.0, -125.0)      # 右嘴角
  29.     ], dtype=np.float32)

  30.     image_pts = np.float32([shape[i] for i in [30, 8, 36, 45, 48, 54]])
  31.     size = frame.shape
  32.     focal_length = size[1]
  33.     center = (size[1] // 2, size[0] // 2)
  34.     camera_matrix = np.array(
  35.         [[focal_length, 0, center[0]],
  36.          [0, focal_length, center[1]],
  37.          [0, 0, 1]], dtype="double"
  38.     )

  39.     dist_coeffs = np.zeros((4, 1))
  40.     (success, rotation_vector, translation_vector) = cv2.solvePnP(
  41.         object_points, image_pts, camera_matrix, dist_coeffs, flags=cv2.SOLVEPNP_ITERATIVE
  42.     )

  43.     rmat, _ = cv2.Rodrigues(rotation_vector)
  44.     angles, _, _, _, _, _ = cv2.RQDecomp3x3(rmat)
  45.     return angles

  46. # 定義眼睛縱橫比閾值和連續(xù)幀數(shù)閾值
  47. EYE_AR_THRESH = 0.3
  48. EYE_AR_CONSEC_FRAMES = 48

  49. # 初始化計(jì)數(shù)器
  50. COUNTER = 0
  51. TOTAL = 0

  52. # 創(chuàng)建鎖對(duì)象
  53. lock = threading.Lock()

  54. # 打開攝像頭
  55. cap = cv2.VideoCapture(60)
  56. cap.set(cv2.CAP_PROP_FRAME_WIDTH, 480)  # 降低分辨率
  57. cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 320)

  58. # 初始化幀計(jì)數(shù)器和時(shí)間戳
  59. fps_counter = 0
  60. start_time = time.time()

  61. # 多線程處理函數(shù)
  62. def process_frame(frame):
  63.     global COUNTER, TOTAL
  64.     gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
  65.     faces = detector(gray, 0)  # 第二個(gè)參數(shù)為0,表示不使用upsampling

  66.     for face in faces:
  67.         landmarks = predictor(gray, face)
  68.         shape = [(landmarks.part(i).x, landmarks.part(i).y) for i in range(68)]
  69.         
  70.         left_eye = shape[36:42]
  71.         right_eye = shape[42:48]

  72.         left_ear = eye_aspect_ratio(left_eye)
  73.         right_ear = eye_aspect_ratio(right_eye)
  74.         ear = (left_ear + right_ear) / 2.0

  75.         if ear < EYE_AR_THRESH:
  76.             with lock:
  77.                 COUNTER += 1
  78.         else:
  79.             with lock:
  80.                 if COUNTER >= EYE_AR_CONSEC_FRAMES:
  81.                     TOTAL += 1
  82.                 COUNTER = 0

  83.         # 繪制68個(gè)特征點(diǎn)
  84.         for n in range(0, 68):
  85.             x, y = shape[n]
  86.             cv2.circle(frame, (x, y), 2, (0, 255, 0), -1)

  87.         cv2.putText(frame, f"Eye AR: {ear:.2f}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)
  88.         cv2.putText(frame, f"Blink Count: {TOTAL}", (10, 60), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)

  89.         # 計(jì)算頭部姿勢(shì)
  90.         angles = get_head_pose(shape)
  91.         pitch, yaw, roll = angles
  92.         cv2.putText(frame, f"Pitch: {pitch:.2f}", (10, 120), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)
  93.         cv2.putText(frame, f"Yaw: {yaw:.2f}", (10, 150), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)
  94.         cv2.putText(frame, f"Roll: {roll:.2f}", (10, 180), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)

  95.         # 判斷疲勞狀態(tài)
  96.         if COUNTER >= EYE_AR_CONSEC_FRAMES or abs(pitch) > 30 or abs(yaw) > 30 or abs(roll) > 30:
  97.             cv2.putText(frame, "Fatigue Detected!", (10, 210), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 255), 2)

  98.     return frame

  99. with ThreadPoolExecutor(max_workers=2) as executor:
  100.     future_to_frame = {}
  101.     while True:
  102.         ret, frame = cap.read()
  103.         if not ret:
  104.             break

  105.         # 提交當(dāng)前幀到線程池
  106.         future = executor.submit(process_frame, frame.copy())
  107.         future_to_frame[future] = frame

  108.         # 獲取已完成的任務(wù)結(jié)果
  109.         for future in list(future_to_frame.keys()):
  110.             if future.done():
  111.                 processed_frame = future.result()
  112.                 cv2.imshow("Frame", processed_frame)
  113.                 del future_to_frame[future]
  114.                 break

  115.         # 計(jì)算幀數(shù)
  116.         fps_counter += 1
  117.         elapsed_time = time.time() - start_time
  118.         if elapsed_time > 1.0:
  119.             fps = fps_counter / elapsed_time
  120.             fps_counter = 0
  121.             start_time = time.time()
  122.             cv2.putText(processed_frame, f"FPS: {fps:.2f}", (10, 90), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)

  123.         if cv2.waitKey(1) & 0xFF == ord('q'):
  124.             break

  125. # 釋放攝像頭并關(guān)閉所有窗口
  126. cap.release()
  127. cv2.destroyAllWindows()
復(fù)制代碼

【總結(jié)】
【米爾MYC-LR3576核心板及開發(fā)板】
這塊開發(fā)板性能強(qiáng)大,能輕松實(shí)現(xiàn)對(duì)人臉的疲勞檢測(cè),通過計(jì)算結(jié)果后進(jìn)入非常多的工業(yè)、人工智能等等的實(shí)用功能。
本文地址:http://m.qingdxww.cn/thread-878896-1-1.html     【打印本頁(yè)】

本站部分文章為轉(zhuǎn)載或網(wǎng)友發(fā)布,目的在于傳遞和分享信息,并不代表本網(wǎng)贊同其觀點(diǎn)和對(duì)其真實(shí)性負(fù)責(zé);文章版權(quán)歸原作者及原出處所有,如涉及作品內(nèi)容、版權(quán)和其它問題,我們將根據(jù)著作權(quán)人的要求,第一時(shí)間更正或刪除。
您需要登錄后才可以發(fā)表評(píng)論 登錄 | 立即注冊(cè)

廠商推薦

  • Microchip視頻專區(qū)
  • FPGA設(shè)計(jì)流程培訓(xùn)教程
  • Chiptorials ——如何將CryptoAuthLib庫(kù)用于Microchip安全身份驗(yàn)證IC
  • Chiptorials ——使用ATECC608 TrustFLEX實(shí)現(xiàn)基本非對(duì)稱身份驗(yàn)證
  • 無線充電基礎(chǔ)知識(shí)及應(yīng)用培訓(xùn)教程
  • 貿(mào)澤電子(Mouser)專區(qū)

相關(guān)視頻

關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點(diǎn)地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權(quán)所有   京ICP備16069177號(hào) | 京公網(wǎng)安備11010502021702
快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 四虎精品免费国产成人 | 日韩美女影院 | 久久久久久久99视频 | 欧美 日韩 成人 | 久久福利资源网站免费看 | 精品视频在线播放 | 色精品视频 | 国内精品影院久久久久 | 欧美日韩国产一区二区三区不卡 | 日本在线视频观看 | 操操操综合| 欧美日韩精品一区二区 | 国产三级精品播放 | 在线精品自拍亚洲第一区 | 中文字幕日本不卡 | 在线a久青草视频在线观看g | 国产精品国产精品 | 男女交配在线观看 | 99这里只有精品视频 | 免费一级毛片在线播放放视频 | 色综合久久久久久久久五月 | 成年人视频免费在线播放 | 一级特黄aaa大片在 一级特黄aaa大片免费看 | 深夜久久 | 男人天堂国产 | 欧美日韩在线一区二区三区 | 永久福利视频 | 羞羞视频网站 | 精品久久久久久国产免费了 | 好男人是视频社区在线 | 亚洲欧美日本国产一区二区三区 | 欧美日韩性生活视频 | 亚洲精品资源在线 | 香蕉蕉亚亚洲aav综合 | 亚洲福利影院 | 国产麻豆精品 | a男人天堂| 青青青久热国产精品视频 | 噜噜在线 | 成人欧美精品久久久久影院 | 最新国产成人盗摄精品视频 |