-1

I have made a code to stimulate the game using face detection. I find the centre of the face and upon its movement, I press the keys with pynput library. The code is working perfectly fine but its just a small issue whenever it detects a movement of the point it presses the keyboard key more than once. I want to limit the pressed key to 1.

'''

import cv2
import numpy as np
from pynput.keyboard import Key, Controller
import time

keyboard = Controller()

wc = cv2.VideoCapture(0)
time.sleep(2)

for i in range(40):
    ret, img = wc.read()

img = cv2.flip(img,1)
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(imgGray, 1.1, 4)
for (x, y, w, h) in faces:
   cv2.rectangle(img, (x,y), (x + w, y + h), (255, 0, 0), 2)
centre = [int((x + w + x)/2), int((y + h + y)/2)]
    


faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
wc = cv2.VideoCapture(0)
    
# Read until video is completed
while(wc.isOpened()):
  # Capture frame-by-frame
  ret, img = wc.read()
  img = cv2.flip(img,1)
  if ret == True:
    
    imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = faceCascade.detectMultiScale(imgGray, 1.1, 4)
    for (x, y, w, h) in faces:
        cv2.rectangle(img, (x,y), (x + w, y + h), (255, 0, 0), 2)
    centre_new = [int((x + w + x)/2), int((y + h + y)/2)]
    cv2.circle(img, (centre_new[0], centre_new[1]), 0, (0,0,255), 5)
    
    if  centre_new[0] - centre[0] > 100 : 
        keyboard.press(Key.right)
        keyboard.release(Key.right)
        print('right')

    if  centre_new[0] - centre[0] < -100 : 
        keyboard.press(Key.left)
        keyboard.release(Key.left)
        print('left')

    if  centre_new[1] - centre[1] < -100 : 
        keyboard.press(Key.up)
        keyboard.release(Key.up)
        print('up') 
    
    if  centre_new[1] - centre[1] > 100 : 
        keyboard = Controller()
        keyboard.press(Key.down)
        keyboard.release(Key.down)
        print('down')

    # Display the resulting frame
    cv2.imshow('Face',img)

    # Press Q on keyboard to  exit
    if cv2.waitKey(1) & 0xFF == ord('q'):
      break
  
  # Break the loop
  else: 
    break

# When everything done, release the video capture object
wc.release()
# Closes all the frames
cv2.destroyAllWindows()

'''

I get this kind of output:

''' up up up up up up up right right right right right right right right right up up up up up

'''

1 Answers1

0

Define some home zone where face should return to distinguish one keystroke from another and use flag to watch it. Is this what you looking for?

keystroke_zone = 100
home_zone = keystroke_zone - 10  # or whatever smaller than 
is_home = True

while(wc.isOpened()):

    ...

    if is_home:
        if centre_new[0] - centre[0] > keystroke_zone : 
            keyboard.press(Key.right)
            keyboard.release(Key.right)
            print('right')
            is_home = False

        if centre_new[0] - centre[0] < -keystroke_zone : 
            keyboard.press(Key.left)
            keyboard.release(Key.left)
            print('left')
            is_home = False

        if centre_new[1] - centre[1] < -keystroke_zone : 
            keyboard.press(Key.up)
            keyboard.release(Key.up)
            print('up')
            is_home = False

        if centre_new[1] - centre[1] > keystroke_zone : 
            keyboard = Controller()
            keyboard.press(Key.down)
            keyboard.release(Key.down)
            print('down')
            is_home = False
    else:
        if abs(centre_new[0] - centre[0]) < home_zone or\
                abs(centre_new[1] - centre[1]) < home_zone:
            is_home = True
Powercoder
  • 695
  • 1
  • 5
  • 25