提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
试验下在主进程中用opencv画个窗口及按钮,点击后退出子进程。
提示:以下是本篇文章正文内容,下面案例可供参考
一、opencv的setMouseCallback函数
- setMouseCallback(winName, onMouse, Param) 有三个参数:
winName 是事先用namedWindwo() 命名的一个窗口
onMouse 是回调函数,当发生鼠标事件时的处理函数
Parm: 待详细了解 - 回调函数 需要自己定义,但是回调函数的参数是固定的:
onMouse(EVENT, x, y, flags, Param)
EVENT 是鼠标事件,比如左键按下什么的
x,y 是鼠标事件发生时鼠标的坐标
前3个参数都是setMouseCallback()函数调用这个函数时自动填入的。
示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
二、试下Queue
- 注意Queue要用Manager()下的Queue()
- 为调试时安全起见,增加了keyboard的hotkey来退出。加上opencv的waitKey(), 所以实际上有3种退出途径。
import cv2
import numpy as np
import multiprocessing
from multiprocessing import Pool, Manager
import time
import keyboard
def closeByMouse(event,x,y,flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
if(70< x < 130) and (70 <y < 130):
global blStop
blStop = True
print('Button was clicked by mouse!')
def quitByHotkey():
global blStop
blStop = True
def subProcess(q):
while q.empty():
print('Subprocess is working!')
time.sleep(10)
q.get()
q.put('OK, subprocess closed')
if __name__ == "__main__":
q = Manager().Queue()
p = Pool(1)
p.apply_async(subProcess,(q,))
p.close()
blStop = False
keyboard.add_hotkey('ctrl+alt+e',quitByHotkey)
canvas = np.ones((200,200,3),np.uint8)*255
cv2.rectangle(canvas,(70,70),(130,130),(127,127,127),3)
cv2.line(canvas,(73,133),(133,133),(120,120,120),3)
cv2.line(canvas,(133,73),(133,133),(120,120,120),3)
cv2.putText(canvas,'Quit',(75,100),cv2.FONT_HERSHEY_PLAIN,1,(0,0,255))
cv2.namedWindow('MainWin')
cv2.setMouseCallback('MainWin', closeByMouse)
cv2.imshow('MainWin',canvas)
count = 0
while count < 100 and not blStop:
cv2.imshow('MainWin',canvas)
if cv2.waitKey(5000) == ord('q'):
print('quit by q!')
blStop = True
cv2.destroyAllWindows()
print('notify subprocess to close!')
q.put('Close!')
time.sleep(10)
print(str(q.get(True,30)))
- Queue有一个问题,就是自己放进去的会被自己取出来,在这个场景下不方便。
三、试下Pipe
- Pipe 用起来还是比较方便的,收发两条线,比较清晰。
- 要注意的是, 检查pipe 里有没有数据的poll()方法,返回True, False, 它并不会触发Timeout Exception. 要用if 语句来判断。
代码如下:
import cv2
import numpy as np
import multiprocessing
from multiprocessing import Pool, Manager
import time
import keyboard
def closeByMouse(event,x,y,flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
if(70< x < 130) and (70 <y < 130):
global blStop
blStop = True
print('Button was clicked by mouse!')
def quitByHotkey():
global blStop
blStop = True
def subProcess(connSub):
blContinue = True
while blContinue:
print('Subprocess is working!')
time.sleep(3)
if connSub.poll(1):
print('subprocess got message from main process: %s'%str(connSub.recv()))
connSub.send('OK, subprocess closed')
blContinue = False
if __name__ == "__main__":
#q = Manager().Queue()
connMain, connSub = multiprocessing.Pipe()
p = Pool(1)
p.apply_async(subProcess,(connSub,))
p.close()
blStop = False
keyboard.add_hotkey('ctrl+alt+e',quitByHotkey)
canvas = np.ones((200,200,3),np.uint8)*255
cv2.rectangle(canvas,(70,70),(130,130),(127,127,127),3)
cv2.line(canvas,(73,133),(133,133),(120,120,120),3)
cv2.line(canvas,(133,73),(133,133),(120,120,120),3)
cv2.putText(canvas,'Quit',(75,100),cv2.FONT_HERSHEY_PLAIN,1,(0,0,255))
cv2.namedWindow('MainWin')
cv2.setMouseCallback('MainWin', closeByMouse)
cv2.imshow('MainWin',canvas)
count = 0
while count < 100 and not blStop:
cv2.imshow('MainWin',canvas)
if cv2.waitKey(5000) == ord('q'):
print('quit by q!')
blStop = True
cv2.destroyAllWindows()
print('notify subprocess to close!')
connMain.send('Close!')
time.sleep(10)
try:
connMain.poll(30)
print(str(connMain.recv()))
except:
print('time out! No feedback from subprocess, quit anyway!')