python - 在 GUI 中模拟从一个无限循环到另一个无限循环的键盘按下
问题描述
我正在尝试做一个 GUI,用户将通过眨眼来控制按钮。基本上,短暂的闪烁应该模拟按下键盘键 Tab(从一个按钮移动到另一个按钮),而长时间的闪烁应该模拟按下键 Space(输入所选按钮)。
这个想法是,窗口和眨眼检测系统这两个进程同时运行。所以在这里我遇到了所有问题:因为它们都是 while 循环,所以我不能同时运行它们。
在我附加的代码中,我通过首先打开主窗口然后单击开始按钮来运行 eyeblink 系统来简化此操作。使用 pyautogui.press() 我想模拟主窗口中的键盘按下。但是,当眨眼检测系统工作时,主窗口不再可访问(您不能按任何东西)。
我试图唤起每一帧的闪烁功能,而不是无限循环,但它太慢并且无法正确检测到闪烁。我也尝试过多处理和“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()
解决方案
推荐阅读
- c - C - 宏检测到错误的数据类型
- mpandroidchart - 如何在 MPandroidchart 库的水平条形图中将 x 轴标签包装成多行?
- python - 当测试没有在 Python 中引发错误时,执行代码的最佳方法是什么?
- c++ - 定义字符串文字
- azure-databricks - 在具有多行数据的 csv 上创建表时出现问题
- perl - Perl 查找另一个数组中存在的一个数组中的缺失元素
- mqtt - Mosquitto 配置日志问题
- java - 如何解析 Thymeleaf 模板以通过电子邮件发送?
- solr - 将所有 Solr 核心数据备份到 SQL 数据库
- sql - SQL 先使用 SUM 然后使用 MAX 函数查找结果集