【项目背景】 
坐在电脑前,时间长了,眼睛不免有些看不清,就愿意往前凑,越来越近。有网友在电脑前使用超声波检测人与屏幕的距离,这可能会受到肢体的干扰。而电脑一般都配有摄像头,这个设备我们可以利用起来。 
【项目设计】 
在Mind+Python模式下,通过mediapipe库检测人脸,提取在摄像头的宽度值,以此判断与屏幕的距离。通过Pinpong库控制Arduino,用LED灯提醒。并pynput库,模拟键盘和鼠标操作,“Ctrl+鼠标滚轮”放大和缩小网面上的文字。 
【技术亮点】 
使用Python中列表的“队列”功能。 
队列,其实就是一个先进先出的线性表,只能在队首执行删除操作,在队尾执行插入操作。用列表表示队列,可以用append()方法实现在队尾插入元素,用pop(0)方法实现在队首删除元素。 
【人脸检测】通过mediapipe库,进行人脸检测,并找到人脸的宽:detection.location_data.relative_bounding_box.width 
  
			
			
			- 
 - 
 - import cv2
 - import mediapipe as mp
 - mp_face_detection = mp.solutions.face_detection
 - mp_drawing = mp.solutions.drawing_utils
 - 
 - # For webcam input:
 - cap = cv2.VideoCapture(0)
 - with mp_face_detection.FaceDetection(min_detection_confidence=0.5) as face_detection:
 -   while cap.isOpened():
 -     success, image = cap.read()
 -     if not success:
 -       print("Ignoring empty camera frame.")
 -       # If loading a video, use 'break' instead of 'continue'.
 -       continue
 - 
 -     # To improve performance, optionally mark the image as not writeable to
 -     # pass by reference.
 -     image.flags.writeable = False
 -     image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
 -     results = face_detection.process(image)
 - 
 -     # Draw the face detection annotations on the image.
 -     image.flags.writeable = True
 -     image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
 -     if results.detections:
 -       for detection in results.detections:
 -         mp_drawing.draw_detection(image, detection)
 -       print(detection.location_data.relative_bounding_box.width)
 -     # Flip the image horizontally for a selfie-view display.
 -     cv2.imshow('MediaPipe Face Detection', cv2.flip(image, 1))
 -     if cv2.waitKey(5) & 0xFF == 27:
 -       break
 - cap.release()
 
  复制代码
  
 
【亮灯提醒】 
 
通过mediapipe人脸检测,人脸在摄像头上会出现近大远小的情况,以脸在摄像头中的宽度来判断,人眼是否离屏幕过近。当超过阈值时(过近),LED提醒。 
  
- 
 - 
 - import cv2
 - import mediapipe as mp
 - from pinpong.board import Board,NeoPixel,Pin
 - 
 - Board("uno").begin()
 - NEOPIXEL_PIN = Pin(Pin.D2)
 - PIXELS_NUM = 60 #灯数
 - np = NeoPixel(NEOPIXEL_PIN,PIXELS_NUM)
 - 
 - mp_face_detection = mp.solutions.face_detection
 - mp_drawing = mp.solutions.drawing_utils
 - np.clear()
 - # For webcam input:
 - cap = cv2.VideoCapture(0)
 - with mp_face_detection.FaceDetection(min_detection_confidence=0.5) as face_detection:
 -   while cap.isOpened():
 -     success, image = cap.read()
 -     if not success:
 -       print("Ignoring empty camera frame.")
 -       # If loading a video, use 'break' instead of 'continue'.
 -       continue
 - 
 -     # To improve performance, optionally mark the image as not writeable to
 -     # pass by reference.
 -     image.flags.writeable = False
 -     image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
 -     results = face_detection.process(image)
 - 
 -     # Draw the face detection annotations on the image.
 -     image.flags.writeable = True
 -     image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
 -     if results.detections:
 -       for detection in results.detections:
 -         mp_drawing.draw_detection(image, detection)
 -       if detection.location_data.relative_bounding_box.width>0.4:
 -           np.rainbow(0,60,0,0x00FF00)
 -       else:
 -           np.clear()    
 -     # Flip the image horizontally for a selfie-view display.
 -     cv2.imshow('MediaPipe Face Detection', cv2.flip(image, 1))
 -     if cv2.waitKey(5) & 0xFF == 27:
 -       break
 - cap.release()
 
  复制代码
  
【模拟放大操作】 
通过pynput库,模拟键盘和鼠标操作,“Ctrl+鼠标滚轮”放大和缩小网面上的文字。 
- 
 - import pynput
 - import time
 - keyboard =pynput.keyboard.Controller()
 - key=pynput.keyboard.Key
 - mouse = pynput.mouse.Controller()
 - time.sleep(10)
 - keyboard.press(key.ctrl)
 - mouse.scroll(0, 50)
 - keyboard.release(key.ctrl)
 
  复制代码
  
【完整代码】 
- 
 - import cv2
 - import mediapipe as mp
 - from pinpong.board import Board,NeoPixel,Pin
 - from pykeyboard import *
 - import pynput
 - import numpy as npy
 - import time
 - Board("uno").begin()
 - NEOPIXEL_PIN = Pin(Pin.D2)
 - PIXELS_NUM = 60 #灯数
 - np = NeoPixel(NEOPIXEL_PIN,PIXELS_NUM)
 - np.clear()
 - mp_face_detection = mp.solutions.face_detection
 - mp_drawing = mp.solutions.drawing_utils
 - keyboard =pynput.keyboard.Controller()
 - key=pynput.keyboard.Key
 - mouse = pynput.mouse.Controller()
 - scrollnum=25
 - bs=0
 - # For webcam input:
 - cap = cv2.VideoCapture(0)
 - scroll=[]
 - bs1=0
 - with mp_face_detection.FaceDetection(min_detection_confidence=0.5) as face_detection:
 -   while cap.isOpened():
 -     success, image = cap.read()
 -     if not success:
 -       print("Ignoring empty camera frame.")
 -       # If loading a video, use 'break' instead of 'continue'.
 -       continue
 - 
 -     # To improve performance, optionally mark the image as not writeable to
 -     # pass by reference.
 -     image.flags.writeable = False
 -     image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
 -     results = face_detection.process(image)
 - 
 -     # Draw the face detection annotations on the image.
 -     image.flags.writeable = True
 -     image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
 -     if results.detections:
 -       for detection in results.detections:
 -         mp_drawing.draw_detection(image, detection)
 -         width=detection.location_data.relative_bounding_box.width
 -       if bs1<10:
 -           bs1=bs1+1
 -           scroll.append(width)
 -       else:
 -           scroll.append(width)
 -           scroll.pop(0)
 -           width=npy.mean(scroll)
 -           if width>0.5:
 -             np.rainbow(0,60,0,0x00FF00)
 -             bs=1
 -           elif bs==1:
 -             bs=0
 -             np.clear()
 -           else:
 -             width=int(width*100/10)
 -             if width!=scrollnum:
 -               temp=-width+scrollnum
 -               keyboard.press(key.ctrl)
 -               mouse.scroll(0, temp*10)#向上滚动50单位
 -               keyboard.release(key.ctrl)
 -               scrollnum=width
 -               print(width)
 - 
 -     # Flip the image horizontally for a selfie-view display.
 -     cv2.imshow('MediaPipe Face Detection', cv2.flip(image, 1))
 -     if cv2.waitKey(5) & 0xFF == 27:
 -       break
 - cap.release()
 
  复制代码
  
【演示视频】 
 
 
 
 
 
 |