opencv GUI中的并行任务

jjjwad0x  于 2023-08-06  发布在  其他
关注(0)|答案(1)|浏览(88)

我正在尝试创建一个机器的控制面板,它有几个网络摄像头来远程监控状态。
我目前使用PySimpleGUI作为图形界面,我将主窗口分为两部分:

  • 左栏:在命令面板中,我有控制机器所需的所有按钮和其他东西
  • 右列:网络摄像头查看器,这里我放了两个Image对象,每隔“refresh_time”(当前为0.5s)从网络摄像头提要更新一次

当我尝试连接到网络摄像头时出现问题。我使用cv2.VideoCapture(url)命令,调用该命令时,它需要几分之一秒的响应时间。每次网络摄像头刷新时重复两次这种延迟,并将其放入控制窗口和其他所有内容的while循环中,从而有效地冻结了几乎一秒钟的所有内容。
显然,结果是一个相当滞后的窗口,更糟糕的是,我在其中一个命令中输入的动画在网络摄像头刷新之间平滑地移动,然后跳转到与实际时间同步。
这是网络摄像头显示的示例代码:

#Main window loop
while True:

    # update current time of the window
    current_time = time.time()-start_time
    
    # get window values for GUI interaction
    event, values = window.read(timeout=15)
    
    #WINDOW CLOSED
    if event == sg.WIN_CLOSED or event == 'Exit':
        capture1.release()
        capture2.release()
        cv2.destroyAllWindows()
        break
 #%% --------------------> WEBCAM DISPLAY <----------------------------
    # # WEBCAM CAPTURING

    if current_time-last_time > refresh_time:
        last_time = current_time
        #Try camera connection
        try:
            # get camera frame
            #requests.get(url1, timeout = 0.5) this was even slower
            capture1 = cv2.VideoCapture(url1)
            ret1, frameOrig1 = capture1.read()
            #if the camera can be read, update the frame and display the image
            frame1 = cv2.resize(frameOrig1, frameSize)
            imgbytes1 = cv2.imencode(".png", frame1)[1].tobytes()
            window["cam1"].update(data=imgbytes1)
            capture1.release()
        except:
            #if the camera can't be read display static image
            window["cam1"].update(data=staticGIF_data)    
    
        # # update webcam2
        try:
            # get camera frame
            #requests.get(url2, timeout = 0.5) this was even slower
            capture2 = cv2.VideoCapture(url2)     
            ret2, frameOrig2 = capture2.read()
            #if the camera can be read, update the frame and display the image
            frame2 = cv2.resize(frameOrig2, frameSize)
            imgbytes2 = cv2.imencode(".png", frame2)[1].tobytes()
            window["cam2"].update(data=imgbytes2)
            capture2.release()
        except:
            #if the camera can't be read display static image
            window["cam2"].update(data=staticGIF_data)

        cv2.destroyAllWindows()

字符串
我的想法是将视频捕获部分代码从窗口while循环中取出,并让它在后台连续运行,可能会将jpg图像更新到程序文件夹中,然后从主循环中读取。
是否可以并行运行第二个循环?我知道有一些库允许进程的并行化,但我需要将整个东西导出到.exe中供最终用户使用,我担心并行化将很难实现。
在此先谢谢您!

lg40wkob

lg40wkob1#

尝试使用多处理器中的Process和manger。
此示例代码可以帮助您:

from multiprocessing import Process, Manager

def getImage(image,url, staticImage):
    lastCamTime = time.time()
    while True:
        if refresh_time < time.time()-lastCamTime:
            lastCamTime = time.time()
            try:
                # get camera frame
                # requests.get(url1, timeout = 0.5) this was even slower
                capture1 = cv2.VideoCapture(url)
                ret1, frameOrig1 = capture1.read()
                # if the camera can be read, update the frame and display the image
                frame1 = cv2.resize(frameOrig1, frameSize)
                image = cv2.imencode(".png", frame1)[1].tobytes()
                capture1.release()
            except:
                image = staticImage# if the camera can't be read display static image
            lastCamTime = time.time()

#Main window loop
with Manager() as manager:
    cam1Image = manager.Array()
    cam2Image = Manager.Array()
    cam1Process = Process(target=getImage, args(url1,cam1Image,staticGIF_data))
    cam2Process = Process(target=getImage, args(url2, cam2Image, staticGIF_data))
    cam1Process.start()
    cam2Process.start()
    cam1Process.join()
    cam2Process.join()
    while True:
        # update current time of the window
        current_time = time.time() - start_time
        # get window values for GUI interaction
        event, values = window.read(timeout=15)
        # WINDOW CLOSED
        if event == sg.WIN_CLOSED or event == 'Exit':
            capture1.release()
            capture2.release()
            cv2.destroyAllWindows()
            break
        # %% --------------------> WEBCAM DISPLAY <----------------------------
        # # WEBCAM CAPTURING

        if current_time - last_time > refresh_time:
            last_time = current_time
            # Try camera connection
            window["cam1"].update(data=cam1Image))
            # # update webcam2
            window["cam2"].update(data=cam2Image))
            #cv2.destroyAllWindows()  ##I don't understand why you did this every loop

字符串

相关问题