Эмулировать нажатие клавиатуры от одного бесконечного цикла к другому в графическом интерфейсе - PullRequest
0 голосов
/ 19 мая 2018

Я пытаюсь сделать графический интерфейс, где пользователь будет управлять кнопками с помощью ссылок.По сути, короткое мигание должно эмулировать нажатие клавиши Tab (для перехода от одной кнопки к другой), а длительное мигание должно эмулировать нажатие клавиши Space (для входа в выбранную кнопку).

Идея состоит в том, что оба процесса, окно и система распознавания глаз, работают одновременно.Итак, здесь я получаю все проблемы: поскольку они оба являются циклами, я не могу их запустить одновременно.

В коде, который я прилагаю, я упрощаю это, открывая сначала главное окно и затем нажимая кнопку Старт, чтобы запустить систему eyeblink.Предполагается, что с pyautogui.press () эмулировать нажатие клавиатуры в главном окне.Однако, когда работает система обнаружения eyeblink, главное окно больше не доступно (вы ничего не можете нажать).

Я пытался вызывать функцию мерцания каждый кадр вместо бесконечного цикла, но он слишком медленный и не может правильно определить мигания.Я также попробовал многопроцессорность и «Python неожиданно завершает работу», ошибки не было, поэтому я не уверен, что происходит (код, который я использовал для этого, приведен в конце, прокомментирован).Я также пробовал многопоточность, но простым способом - без ошибок, но ничего не появляется (опять же, код, который я использовал, чтобы попробовать это, в конце прокомментирован).Здесь я прилагаю ссылку на файлы (.mp3, .xml, .py): https://drive.google.com/drive/folders/1U2uwHXzl2MtSTlAKw1L68L3xcRmelP2d?usp=sharing

Я только начал использовать Python, поэтому мои знания не высоки, у меня заканчивается время иЯ застрял в этой точке ... Так что любая помощь будет приветствоваться!Заранее спасибо;)

MacOs Python 2.7 OpenCV 3.4 Tkinter (я просто выбрал его, потому что он прост в обращении, но я готов к изменениям, если это необходимо)

# Ventana+Blink
from Tkinter import *
import numpy as np
import cv2
# To emulate a keyboard pressing
import pyautogui
import time
# To play the sounds
import subprocess 
# from Blink import funcion_blink
# from multiprocessing import Process
# import threading 


def Onbutton_clicked():
    # while True:
    # Repeating 2 times the sound
    for x in range (0,2):
        subprocess.call(['afplay', 'alarm2.mp3'])

def Onbutton2_clicked():
    # Repeating 1 times the sound
    for x in range (0,1):
        subprocess.call(['afplay', 'sound.mp3'])


def execute_func1():
    print('enter\n')
    pyautogui.press('space')  # press the Space key
    for x in range (1,2):
        subprocess.call(['afplay', 'unconvinced.mp3'])

def execute_func2():
    print('tab\n')
    pyautogui.press('tab')  # press the Tab key
    for x in range (1,2):
        subprocess.call(['afplay', 'case-closed.mp3'])

def execute_func3():
    print('space\n')
    pyautogui.press('space')  # press the Space key
    for x in range (1,2):
        subprocess.call(['afplay', 'cheerful.mp3'])


# ----- Eyeblink detection system -----
def funcion_blink():
#XML classifiers should be in the folder with this file
    face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
    eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')

    video_capture = cv2.VideoCapture(0)
    det = 0
    n = 0

    while True:
    # Capture frame-by-frame
        ret, frame = video_capture.read()
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        faces = face_cascade.detectMultiScale(
            gray,
            scaleFactor=1.1,
            minNeighbors=5,
            minSize=(100, 100),
            flags=cv2.CASCADE_SCALE_IMAGE
        )

            # Draw a rectangle around the faces
        for (x, y, w, h) in faces:
            cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
            roi_gray = gray[y:y + h, x:x + w]
            roi_color = frame[y:y + h, x:x + w]
            eyes = eye_cascade.detectMultiScale(
                roi_gray,
                scaleFactor = 1.1,
                minNeighbors = 5,
                minSize = (30, 30),
                flags = cv2.CASCADE_SCALE_IMAGE
            )
            for (ex, ey, ew, eh) in eyes:
                cv2.rectangle(roi_color, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 2)
            face_img = gray[x:x + w, y:y + h]
            face_res = cv2.resize(face_img, (100, 100), interpolation=cv2.INTER_CUBIC)
            eye_reg = face_res[15:85, 20:50]
            cv2.rectangle(frame, (x+15*w/100, y + 2*h / 10), (x + w*85/100, y + (5 * h / 10)), (0, 0, 255), 2)
            if (det < 10):
                tmpl_eyes = eye_reg
                det = det + 1
                print('template acquired\n')
            elif (det == 10):
                        # template matching
                wt, ht = tmpl_eyes.shape[::-1]
                        #res_templ = cv2.matchTemplate(eye_reg, tmpl_eyes, cv2.TM_CCORR_NORMED)
                res_templ = cv2.matchTemplate(eye_reg, tmpl_eyes, cv2.TM_CCOEFF_NORMED)
                min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res_templ)
                            # print(max_val, n)
                        #value 0.92 should be adapted to the conditions and camera position
                if (max_val>0.90):
                    n=n+1
                else:
                    if (n>=12):
                        execute_func1()
                                #here should go the code that triggers some action when the person blinks??                 
                    elif (n>=6):
                        execute_func2()              
                    elif (n>=3):
                        execute_func3()

                    n = 0
                print(max_val, n)

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

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

    # When everything is done, release the capture
    cv2.destroyAllWindows()
    video_capture.release()


# ---- Main window ----
def main_window():
    root= Tk()   
    root.geometry('700x700')

    # Create the buttons of the main window
    button=Button(root, text='alarm', command=Onbutton_clicked)
    button.bind('<Return>', Onbutton_clicked)
    button.pack()

    button2=Button(root, text='extra', command=Onbutton2_clicked)
    button2.bind('<Return>', Onbutton2_clicked)
    button2.pack()

    # By pressing this button we start running the eyeblink detection system
    button3=Button(root, text='Start', command=funcion_blink)
    button3.bind('<Button-1>', funcion_blink)
    button3.pack()

    # To maintain the window until you close it
    root.mainloop()

# Execute the main window
main_window()


# ---- Trials ----

# while True:
#     main_window()
#     funcion_blink()  
# It just plays one function and when it finishes it plays the next one

# Multiprocessing
# if __name__ == '__main__':
#     Process(target=main_window).start()
#     Process(target=funcion_blink).start()
# PYTHON QUITS UNEXPECTADLY

# Threading
# p1 = threading.Thread(target=main_window, args=())
# p2 = threading.Thread(target=funcion_blink, args=())
# p1.start()
# p2.start()
...