2021-12-20 19:38:54 [显示全部楼层]
1357浏览
查看: 1357|回复: 2

Mind+python 防“近视”灯

[复制链接]
【项目背景】
坐在电脑前,时间长了,眼睛不免有些看不清,就愿意往前凑,越来越近。有网友在电脑前使用超声波检测人与屏幕的距离,这可能会受到肢体的干扰。而电脑一般都配有摄像头,这个设备我们可以利用起来。
【项目设计】
在Mind+Python模式下,通过mediapipe库检测人脸,提取在摄像头的宽度值,以此判断与屏幕的距离。通过Pinpong库控制Arduino,用LED灯提醒。并pynput库,模拟键盘和鼠标操作,“Ctrl+鼠标滚轮”放大和缩小网面上的文字。
【技术亮点】
使用Python中列表的“队列”功能。
队列,其实就是一个先进先出的线性表,只能在队首执行删除操作,在队尾执行插入操作。用列表表示队列,可以用append()方法实现在队尾插入元素,用pop(0)方法实现在队首删除元素。
【人脸检测】通过mediapipe库,进行人脸检测,并找到人脸的宽:detection.location_data.relative_bounding_box.width
Mind+python 防“近视”灯图1

  1. import cv2
  2. import mediapipe as mp
  3. mp_face_detection = mp.solutions.face_detection
  4. mp_drawing = mp.solutions.drawing_utils
  5. # For webcam input:
  6. cap = cv2.VideoCapture(0)
  7. with mp_face_detection.FaceDetection(min_detection_confidence=0.5) as face_detection:
  8.   while cap.isOpened():
  9.     success, image = cap.read()
  10.     if not success:
  11.       print("Ignoring empty camera frame.")
  12.       # If loading a video, use 'break' instead of 'continue'.
  13.       continue
  14.     # To improve performance, optionally mark the image as not writeable to
  15.     # pass by reference.
  16.     image.flags.writeable = False
  17.     image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
  18.     results = face_detection.process(image)
  19.     # Draw the face detection annotations on the image.
  20.     image.flags.writeable = True
  21.     image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
  22.     if results.detections:
  23.       for detection in results.detections:
  24.         mp_drawing.draw_detection(image, detection)
  25.       print(detection.location_data.relative_bounding_box.width)
  26.     # Flip the image horizontally for a selfie-view display.
  27.     cv2.imshow('MediaPipe Face Detection', cv2.flip(image, 1))
  28.     if cv2.waitKey(5) & 0xFF == 27:
  29.       break
  30. cap.release()
复制代码


【亮灯提醒】


通过mediapipe人脸检测,人脸在摄像头上会出现近大远小的情况,以脸在摄像头中的宽度来判断,人眼是否离屏幕过近。当超过阈值时(过近),LED提醒。
Mind+python 防“近视”灯图2

  1. import cv2
  2. import mediapipe as mp
  3. from pinpong.board import Board,NeoPixel,Pin
  4. Board("uno").begin()
  5. NEOPIXEL_PIN = Pin(Pin.D2)
  6. PIXELS_NUM = 60 #灯数
  7. np = NeoPixel(NEOPIXEL_PIN,PIXELS_NUM)
  8. mp_face_detection = mp.solutions.face_detection
  9. mp_drawing = mp.solutions.drawing_utils
  10. np.clear()
  11. # For webcam input:
  12. cap = cv2.VideoCapture(0)
  13. with mp_face_detection.FaceDetection(min_detection_confidence=0.5) as face_detection:
  14.   while cap.isOpened():
  15.     success, image = cap.read()
  16.     if not success:
  17.       print("Ignoring empty camera frame.")
  18.       # If loading a video, use 'break' instead of 'continue'.
  19.       continue
  20.     # To improve performance, optionally mark the image as not writeable to
  21.     # pass by reference.
  22.     image.flags.writeable = False
  23.     image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
  24.     results = face_detection.process(image)
  25.     # Draw the face detection annotations on the image.
  26.     image.flags.writeable = True
  27.     image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
  28.     if results.detections:
  29.       for detection in results.detections:
  30.         mp_drawing.draw_detection(image, detection)
  31.       if detection.location_data.relative_bounding_box.width>0.4:
  32.           np.rainbow(0,60,0,0x00FF00)
  33.       else:
  34.           np.clear()   
  35.     # Flip the image horizontally for a selfie-view display.
  36.     cv2.imshow('MediaPipe Face Detection', cv2.flip(image, 1))
  37.     if cv2.waitKey(5) & 0xFF == 27:
  38.       break
  39. cap.release()
复制代码

【模拟放大操作】
通过pynput库,模拟键盘和鼠标操作,“Ctrl+鼠标滚轮”放大和缩小网面上的文字。
  1. import pynput
  2. import time
  3. keyboard =pynput.keyboard.Controller()
  4. key=pynput.keyboard.Key
  5. mouse = pynput.mouse.Controller()
  6. time.sleep(10)
  7. keyboard.press(key.ctrl)
  8. mouse.scroll(0, 50)
  9. keyboard.release(key.ctrl)
复制代码

【完整代码】
  1. import cv2
  2. import mediapipe as mp
  3. from pinpong.board import Board,NeoPixel,Pin
  4. from pykeyboard import *
  5. import pynput
  6. import numpy as npy
  7. import time
  8. Board("uno").begin()
  9. NEOPIXEL_PIN = Pin(Pin.D2)
  10. PIXELS_NUM = 60 #灯数
  11. np = NeoPixel(NEOPIXEL_PIN,PIXELS_NUM)
  12. np.clear()
  13. mp_face_detection = mp.solutions.face_detection
  14. mp_drawing = mp.solutions.drawing_utils
  15. keyboard =pynput.keyboard.Controller()
  16. key=pynput.keyboard.Key
  17. mouse = pynput.mouse.Controller()
  18. scrollnum=25
  19. bs=0
  20. # For webcam input:
  21. cap = cv2.VideoCapture(0)
  22. scroll=[]
  23. bs1=0
  24. with mp_face_detection.FaceDetection(min_detection_confidence=0.5) as face_detection:
  25.   while cap.isOpened():
  26.     success, image = cap.read()
  27.     if not success:
  28.       print("Ignoring empty camera frame.")
  29.       # If loading a video, use 'break' instead of 'continue'.
  30.       continue
  31.     # To improve performance, optionally mark the image as not writeable to
  32.     # pass by reference.
  33.     image.flags.writeable = False
  34.     image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
  35.     results = face_detection.process(image)
  36.     # Draw the face detection annotations on the image.
  37.     image.flags.writeable = True
  38.     image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
  39.     if results.detections:
  40.       for detection in results.detections:
  41.         mp_drawing.draw_detection(image, detection)
  42.         width=detection.location_data.relative_bounding_box.width
  43.       if bs1<10:
  44.           bs1=bs1+1
  45.           scroll.append(width)
  46.       else:
  47.           scroll.append(width)
  48.           scroll.pop(0)
  49.           width=npy.mean(scroll)
  50.           if width>0.5:
  51.             np.rainbow(0,60,0,0x00FF00)
  52.             bs=1
  53.           elif bs==1:
  54.             bs=0
  55.             np.clear()
  56.           else:
  57.             width=int(width*100/10)
  58.             if width!=scrollnum:
  59.               temp=-width+scrollnum
  60.               keyboard.press(key.ctrl)
  61.               mouse.scroll(0, temp*10)#向上滚动50单位
  62.               keyboard.release(key.ctrl)
  63.               scrollnum=width
  64.               print(width)
  65.     # Flip the image horizontally for a selfie-view display.
  66.     cv2.imshow('MediaPipe Face Detection', cv2.flip(image, 1))
  67.     if cv2.waitKey(5) & 0xFF == 27:
  68.       break
  69. cap.release()
复制代码

【演示视频】





glwz007  初级技匠

发表于 2021-12-22 14:40:56

认真学习,谢谢分享!
回复

使用道具 举报

K2dCnC_w  学徒

发表于 2021-12-23 23:32:18

这个根据视线距离调整页面缩放的想法非常有趣
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail