当前位置:   article > 正文

树莓派4B Python3.7 模拟捂眼检测_树莓派cvzone

树莓派cvzone

#继之前安装树莓派3.7python+mediapipe之后,实现了一种通过cvzone(封装了mediapipe)

1使用cvzone里的cvzone.FaceDetectionModule.FaceDetector找到人脸位置获取人脸边框坐标

2通过cvzone里的cvzone.HandTrackingModule.HandDetector找到人手关键点坐标位置

3通过人脸位置的x,y,w,h和手指关键坐标的一点,我使用了小拇指第二关节,一旦检测到小拇指进入了人脸检测区域就可以得到捂眼睛的状态,实测cvzone的人脸检测可以做到半张脸检测到人脸信息,同时两种检测同时进行在i7 笔记本电脑cpu上不会卡顿,移植在树莓派4B上可以通过480p流畅运行,720p略有卡顿,1080p严重卡顿延迟拖影,可能是树莓派本身的视频流处理的原因,我使用过树莓派的两种视频解码模式都效果不是很好,正在持续寻找解决方法。

4在输入参量中cover_mode = 1只检测捂左眼反之 = 2只检测捂右眼。代码可以直接运行

检测过程如下图一,手的关键点坐标如图二:

完整实例代码如下: 

  1. # -*- coding: utf-8 -*-
  2. import cv2
  3. import time
  4. import numpy as np
  5. import cvzone.HandTrackingModule
  6. import cvzone.FaceDetectionModule
  7. face_detector = cvzone.FaceDetectionModule.FaceDetector(minDetectionCon=0.5)
  8. hand_direction_detector = cvzone.HandTrackingModule.HandDetector(mode=False, # 视频流图像
  9. maxHands=4, # 最多检测两只手
  10. detectionCon=0.5, # 最小检测置信度
  11. minTrackCon=0.7) # 最小跟踪置信度
  12. def is_coverings_eye(cap_hand_direction, cover_mode=1, test_time=5):
  13. print("捂眼检测")
  14. atime = time.time()
  15. while True:
  16. success, frame = cap_hand_direction.read()
  17. if success is not True:
  18. break
  19. # frame = cv2.flip(frame, flipCode=1) # 这里是否反转 下面是否反转还得测试
  20. _, face_boxs = face_detector.findFaces(frame, draw=False)
  21. hands = hand_direction_detector.findHands(frame, draw=False, flipType=False)
  22. # 获取人脸边框范围 与人手比较
  23. if face_boxs: # 如果检测到了人脸 在此判断条件下再去检测人手 三种情况 没手 一只手 两只手
  24. max_area = 0 # 初始化最大面积为0
  25. max_index = -1 # 初始化最大面积对应的遍历序号为-1
  26. for index, facebox in enumerate(face_boxs): # 先全部遍历求出面积最大的人脸序号
  27. _, _, w, h = facebox["bbox"]
  28. area = w * h # 计算人脸面积
  29. if area > max_area:
  30. max_area = area
  31. max_index = index
  32. face_x, face_y, face_w, face_h = face_boxs[max_index]['bbox'] # 求出人脸范围
  33. if hands: # 如果有手存在 找到面积最大的左手和右手的序号
  34. left_hand_max_area = 0 # 初始化最大面积为0
  35. right_hand_max_area = 0 # 初始化最大面积为0
  36. left_hand_max_index = -1 # 初始化最大面积对应的遍历序号为-1
  37. right_hand_max_index = -1 # 初始化最大面积对应的遍历序号为-1
  38. left_region_status = 0 # 初始化左手是否在范围内
  39. right_region_status = 0 # 初始化右手是否在范围内
  40. for index, hand in enumerate(hands):
  41. if hand["type"] == "Left" and cover_mode == 1: # 左手
  42. _, _, w_left, h_left = hand["bbox"]
  43. left_hand_area = w_left * h_left # 计算面积
  44. if left_hand_area > left_hand_max_area:
  45. left_hand_max_area = left_hand_area
  46. left_hand_max_index = index
  47. if hand["type"] == "Right" and cover_mode == 2: # 右手
  48. _, _, w_right, h_right = hand["bbox"]
  49. right_hand_area = w_right * h_right # 计算面积
  50. if right_hand_area > right_hand_max_index:
  51. right_hand_max_index = right_hand_area
  52. right_hand_max_index = index
  53. # 这里已经知道人脸范围 同时若index不等于-1 的时候就是有这只手
  54. if left_hand_max_index != -1: # 如果检测到了左手
  55. left_hand_x, left_hand_y = hands[left_hand_max_index]["lmList"][20][:2] # 用小拇指头代表左手
  56. if face_x <= left_hand_x <= face_x + face_w and face_y <= left_hand_y <= face_y + face_h:
  57. left_region_status = 1 # 左手在这个范围里
  58. else:
  59. pass
  60. if right_hand_max_index != -1: # 如果检测到了左手
  61. right_hand_x, right_hand_y = hands[right_hand_max_index]["lmList"][20][:2] # 用小拇指头代表左手
  62. if face_x <= right_hand_x <= face_x + face_w and face_y <= right_hand_y <= face_y + face_h:
  63. right_region_status = 1 # 左手在这个范围里
  64. else:
  65. pass
  66. if left_region_status == 1: # 左手在范围里 就需要检测右手指向
  67. print("左手在范围内")
  68. return 1
  69. if right_region_status == 1:
  70. print("右手在范围内")
  71. return 2
  72. if time.time() - atime > test_time:
  73. return 0
  74. cv2.imshow("test", frame)
  75. if cv2.waitKey(1) & 0xFF == 27: # 每帧滞留20毫秒后消失,ESC键退出
  76. break
  77. if __name__ == '__main__':
  78. print("开始载入视频")
  79. cap = cv2.VideoCapture(0)
  80. cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'))
  81. cap.set(3, 640) # 设置摄像头宽度
  82. cap.set(4, 480) # 设置摄像头高度
  83. print("载入视频完成")
  84. cover_eys_model = is_coverings_eye(cap, cover_mode=1, test_time=40) # cover_mode = 1是检测捂左眼
  85. print(cover_eys_model)
  86. cover_eys_model = is_coverings_eye(cap, cover_mode=2, test_time=40) # cover_mode = 1是检测捂右眼
  87. print(cover_eys_model)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/886452
推荐阅读
相关标签
  

闽ICP备14008679号