@@ -7,6 +7,8 @@ import datetime | |||
import os | |||
import sys | |||
from utils.utils import send_notifycation | |||
import collections | |||
from utils.utils import doNotMove,mouseClick | |||
def getFile(ruleFile): | |||
if getattr(sys, 'frozen', False): | |||
@@ -25,6 +27,10 @@ def get_settings_status_name(data, settings,setting_name): | |||
# 使用 filter() 和 map() 函数提取信息 | |||
names = list(map(lambda x: x["name"], filter(lambda x: x["status"], setting["status"]))) | |||
return names[0] | |||
def get_settings_status_root(data, settings): | |||
# 访问指定 "setting" 的信息 | |||
names = list(map(lambda x: x["name"], filter(lambda x: x["status"], data[settings]))) | |||
return names[0] | |||
def get_setting_status(data, settings,setting_name): | |||
# 使用 filter() 和 map() 函数提取信息 | |||
status = list(map(lambda x: x["status"], filter(lambda x: x["name"] == setting_name, data[settings]))) | |||
@@ -82,6 +88,30 @@ def getModelSetting(args): | |||
model["status"] = False | |||
args["ModelSetting"][0]["status"] = model_dict | |||
return args | |||
def checkAction(queue,type,action,tip): | |||
print(type,action,queue[2]["time"]-queue[0]["time"]) | |||
# 输入一个长度为3的队列,根据情况判断是否执行动作 | |||
if(queue[0]["status"]==0 and queue[1]["status"]==1 and queue[2]["status"]==0 and type=="张开持续1S" and (queue[2]["time"]-queue[0]["time"])>1): | |||
if(action=="悬停鼠标"): | |||
doNotMove() | |||
if(tip): | |||
send_notifycation("触发悬停鼠标","EMC") | |||
elif(action=="单击按钮"): | |||
mouseClick() | |||
if(tip): | |||
send_notifycation("触发单击按钮","EMC") | |||
return True | |||
elif(queue[0]["status"]==1 and queue[1]["status"]==0 and queue[2]["status"]==1 and type=="闭上持续1S" and (queue[2]["time"]-queue[0]["time"])>1): | |||
if(action=="悬停鼠标"): | |||
doNotMove() | |||
if(tip): | |||
send_notifycation("触发悬停鼠标","EMC") | |||
elif(action=="单击按钮"): | |||
mouseClick() | |||
if(tip): | |||
send_notifycation("触发单击按钮","EMC") | |||
return True | |||
return False | |||
class API: | |||
'''本地API,供前端JS调用''' | |||
@@ -89,6 +119,8 @@ class API: | |||
net = None | |||
cap = None | |||
args = None | |||
# 状态队列 | |||
queue = None | |||
def __init__(self): | |||
@@ -108,9 +140,55 @@ class API: | |||
# cv2.namedWindow('Video Cam', cv2.WINDOW_NORMAL) | |||
if(self.args['toggle'] and self.args['tip']): | |||
send_notifycation("功能触发:鼠标悬停","EMC[嘴控]") | |||
send_notifycation("EMC程序已启动","EMC") | |||
self.queue = collections.deque(maxlen=3) | |||
def detectThreading(self): | |||
if self.args['toggle']==False: | |||
pass | |||
result = get_photo_detect(self.cap,self.net) | |||
eye = -1 | |||
mouth = -1 | |||
for i in result: | |||
if i["classid"] == "closed_eye": | |||
eye = 0 | |||
elif i["classid"] == "open_eye": | |||
eye = 1 | |||
elif i["classid"] == "closed_mouth": | |||
mouth = 0 | |||
elif i["classid"] == "open_mouth": | |||
mouth = 1 | |||
status = -1 | |||
if get_settings_status_root(self.args,"control") == "嘴控": | |||
if(mouth==0): | |||
status = 0 | |||
elif(mouth==1): | |||
status = 1 | |||
elif get_settings_status_root(self.args,"control") == "眼控": | |||
if(eye==0): | |||
status = 0 | |||
elif(eye==1): | |||
status = 1 | |||
elif get_settings_status_root(self.args,"control") == "嘴/眼控": | |||
if(mouth==0 or eye==0): | |||
status = 0 | |||
elif(mouth==1 or eye==1): | |||
status = 1 | |||
if(status!=-1): | |||
if(len(self.queue)<3 or status!=self.queue[-1]["status"]): | |||
self.queue.append({"status":status,"time":time.time()}) | |||
if(len(self.queue)==3): | |||
if(checkAction(self.queue,get_settings_status_name(self.args,"ControlSetting","控制设置"),get_settings_status_name(self.args,"ControlSetting","控制功能"),self.args['tip'])): | |||
self.queue.clear()#执行动作则清空队列 | |||
else: | |||
self.queue[-1]["time"]=time.time() | |||
print(self.queue) | |||
def getPrimaryImg(self,type="不裁剪"): | |||
# 三种处理图片的方式:不裁剪、居中裁剪成224*224、居中裁剪成320*320。 | |||
@@ -7,11 +7,11 @@ | |||
"control": [ | |||
{ | |||
"name": "嘴控", | |||
"status": false | |||
"status": true | |||
}, | |||
{ | |||
"name": "眼控", | |||
"status": true | |||
"status": false | |||
}, | |||
{ | |||
"name": "嘴/眼控", | |||
@@ -23,19 +23,11 @@ | |||
"name": "控制设置", | |||
"status": [ | |||
{ | |||
"name": "开/关/开", | |||
"status": false | |||
}, | |||
{ | |||
"name": "关/开/关", | |||
"status": false | |||
}, | |||
{ | |||
"name": "闭上持续2S", | |||
"name": "闭上持续1S", | |||
"status": false | |||
}, | |||
{ | |||
"name": "张开持续2S", | |||
"name": "张开持续1S", | |||
"status": true | |||
} | |||
], | |||
@@ -5,6 +5,6 @@ class Config: | |||
'''配置文件''' | |||
appName = 'EMC' # 应用名称 | |||
appVersion = "1.0.0" # 应用版本号 | |||
appVersion = "1.1.0" # 应用版本号 | |||
appSystem = platform.system() # 本机系统类型 |
@@ -7,6 +7,16 @@ from api.api import API | |||
from config.config import Config | |||
from utils.utils import send_notifycation | |||
from pystray import MenuItem as item | |||
import pystray | |||
from PIL import Image | |||
import threading | |||
import time | |||
# 前端页面目录 | |||
if sys.flags.dev_mode: | |||
MAIN_DIR = os.path.join("..", "dist") # 开发环境 | |||
@@ -19,14 +29,36 @@ else: | |||
def WebViewApp(port,dev=False): | |||
api = API() # 本地接口 | |||
cfg = Config() # 配置文件 | |||
if(dev): | |||
window = webview.create_window(cfg.appName, 'http://localhost:'+str(port)+'/',js_api=api) | |||
webview.start(debug=True, http_server=True) # 启动窗口 | |||
else: | |||
template = os.path.join(MAIN_DIR, "index.html") # 设置页面,可以指向远程或本地 | |||
window = webview.create_window(title=cfg.appName, url=template, js_api=api) # 创建窗口 | |||
api.window=window # 本地接口 | |||
webview.start(debug=DEBUG, http_server=True) # 启动窗口 | |||
def detect(): | |||
api.detectThreading() | |||
global timer | |||
timer = threading.Timer(0.25, detect) # 在回调函数中再次启动定时器 | |||
timer.start() # 启动定时器 | |||
def exitProgram(): | |||
icon.stop() | |||
print("exitProgram") | |||
global timer | |||
timer.cancel() | |||
def action(): | |||
global timer | |||
timer.cancel() | |||
icon.stop() | |||
# icon.visible = False | |||
if(dev): | |||
window = webview.create_window(cfg.appName, 'http://localhost:'+str(port)+'/',js_api=api) | |||
webview.start(debug=True, http_server=True) # 启动窗口 | |||
else: | |||
template = os.path.join(MAIN_DIR, "index.html") # 设置页面,可以指向远程或本地 | |||
window = webview.create_window(title=cfg.appName, url=template, js_api=api) # 创建窗口 | |||
api.window=window # 本地接口 | |||
webview.start(debug=DEBUG, http_server=True) # 启动窗口 | |||
timer = threading.Timer(0.25, detect) # 在回调函数中再次启动定时器 | |||
timer.start() # 启动定时器 | |||
image = Image.open("C:/Users/16775/Pictures/head.jpg") | |||
menu = (item('打开主页面', action), item('退出', exitProgram)) | |||
icon = pystray.Icon("name", image, "title", menu) | |||
icon.run() | |||
if __name__ == "__main__": | |||
@@ -1,5 +1,8 @@ | |||
import subprocess | |||
import os,sys | |||
import pyautogui as pg #没别的作用就单纯换个名字 | |||
import threading | |||
def getFile(ruleFile): | |||
if getattr(sys, 'frozen', False): | |||
absPath = os.path.dirname(os.path.abspath(sys.executable)) | |||
@@ -38,3 +41,20 @@ def send_notifycation (content: str = '', title: str = 'New notifycation', | |||
"".join([d.get(c, c) for c in (s)]) % ( | |||
content, title, tip_type, duration)) | |||
]) | |||
mouseX = False | |||
def doNotMove(): | |||
global mouseX | |||
mouseX = (mouseX==False) #取反 | |||
x,y=pg.position() #核心函数pg.position() | |||
def mouseMove(): | |||
pg.moveTo(x,y) | |||
if(mouseX): | |||
global timer | |||
timer = threading.Timer(0.05, mouseMove) # 设定定时器,每 5 秒执行一次 periodic_function | |||
timer.start() # 启动定时器 | |||
timer = threading.Timer(0.05, mouseMove) # 设定定时器,每 5 秒执行一次 periodic_function | |||
timer.start() # 启动定时器 | |||
def mouseClick(): | |||
pg.click() |