Python多进程通信及opencv实验

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

试验下在主进程中用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!')

实测的效果:

在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_54284125/article/details/122651448