簡體   English   中英

如何通過多重處理將布爾值從一個函數返回到另一個函數?

[英]How to return a Boolean value from one function to another via multiprocessing?

我有四個職能; 三種相機功能(拍照保存圖像,將路徑保存到CSV文件),第四種功能是通過arduino從串行連接中獲取數據。 每個函數都可以按預期方式獨立運行,並且可以通過常規的multiprocessing功能運行(不使用join() )。 由於opencv函數的工作方式,我無法使用join()方法。 我知道join方法有效,它在等待child processes完成之前再次運行它。

我需要能夠從arduino函數向相機函數返回一個值(布爾值:True / False或0/1),然后再重新啟動。 Arduino代碼花費的時間最長,並且需要時間才能運行。 下面的通用代碼

import cv2
import multiprocessing
import Serial


def camera1():
    global cap1
    cap1 = cv2.VideoCapture(0)
    while True:
        _, frame1 = cap1.read()
        cv2.imshow('frame1', frame1)

        k = cv2.waitKey(5)
        if k == 27:
            break
       """
       Saves image and add to csv file
       while loop checking for ard_serial is complete to repeat
       """
    cap1.release()


def camera2():
    global cap2
    cap2 = cv2.VideoCapture(1)
    while True:
        _, frame2 = cap2.read()
        cv2.imshow('frame2', frame2)

        k = cv2.waitKey(5)
        if k == 27:
            break
       """
       Saves image and add to csv file
       while loop checking for ard_serial is complete to repeat
       """
    cap2.release()



def camera3():
    global cap3
    cap3 = cv2.VideoCapture(2)
    while True:
        _, frame3 = cap3.read()
        cv2.imshow('frame3', frame3)

        k = cv2.waitKey(5)
        if k == 27:
            break
       """
       Saves image and add to csv file
       while loop checking for ard_serial is complete to repeat
       """
    cap3.release()


def ard_serial():
   """
   Serial Stuff happens here
   When Complete sends value to cam functions
   to start again.
   """

if __name__ == '__main__':
   for _ in range(20)
       p1 = multiprocessing.Process(target=camera1)
       p1.start()
       p2 = multiprocessing.Process(target=camera2)
       p2.start()
       p3 = multiprocessing.Process(target=camera3)
       p3.start()
       p4 = multiprocessing.Process(target=ard_serial)
       p4.start()
       """
       p1.join()
       p2.join()
       p3.join()
       p4.join()
       """

我需要同時啟動所有四個功能,並讓cam功能等待arduino功能完成再重新啟動。 我該怎么用? 我不確定是否必須使用Queue或其他方法。 另外,大多數示例只有一個返回某些內容的輔助函數。 我需要一個函數將返回值發送給另一個函數。 join()方法將無法工作,因為它可能永遠不會結束,而while循環直到完成

最簡單的方法是將事件用於不同進程之間的信令。

事件是同步處理的一種非常基本的方式。 可以設置它們(= True)或清除它們(= False)。 它們還具有阻止功能,直到事件設置為True為止。 由於它們是線程安全的,因此可以在進程之間共享。

文檔活動

就像是:

import cv2
import multiprocessing
import Serial


def camera1(e):
    global cap1
    cap1 = cv2.VideoCapture(0)
    while True:
        e.wait()
        _, frame1 = cap1.read()
        cv2.imshow('frame1', frame1)

        k = cv2.waitKey(5)
        if k == 27:
            break
       """
       Saves image and add to csv file
       while loop checking for ard_serial is complete to repeat
       """
    cap1.release()


def camera2(e):
    global cap2
    cap2 = cv2.VideoCapture(1)
    while True:
        e.wait()
        _, frame2 = cap2.read()
        cv2.imshow('frame2', frame2)

        k = cv2.waitKey(5)
        if k == 27:
            break
       """
       Saves image and add to csv file
       while loop checking for ard_serial is complete to repeat
       """
    cap2.release()



def camera3(e):
    global cap3
    cap3 = cv2.VideoCapture(2)
    while True:
        e.wait()
        _, frame3 = cap3.read()
        cv2.imshow('frame3', frame3)

        k = cv2.waitKey(5)
        if k == 27:
            break
       """
       Saves image and add to csv file
       while loop checking for ard_serial is complete to repeat
       """
    cap3.release()


def ard_serial(e):
   """
   Serial Stuff happens here
   When Complete sends value to cam functions
   to start again.
   """
        e.clear()
        #do your stuff
        e.set()

if __name__ == '__main__':
   e = multiprocessing.event()
   for _ in range(20)
       p1 = multiprocessing.Process(target=camera1, args=[e,])
       p1.start()
       p2 = multiprocessing.Process(target=camera2, args=[e,])
       p2.start()
       p3 = multiprocessing.Process(target=camera3, args=[e,])
       p3.start()
       p4 = multiprocessing.Process(target=ard_serial, args=[e,])
       p4.start()
       """
       p1.join()
       p2.join()
       p3.join()
       p4.join()
       """

我不確定您是否需要multiprocessing 以下代碼可能有助於突出顯示/解決您遇到的一些問題:

import cv2

caps = {}
for i in range(3):
    cap = cv2.VideoCapture(i)
    # make sure we don't get too far behind
    cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
    caps[i] = cap

首先,打開所有捕獲設備並將其緩沖區大小設置為1幀。 否則,如果您在幀之前等待串行活動,則趨向於獲取較舊/緩沖的幀,而不是實際想要的較新的幀。

接下來我們運行主循環

frame = 0
while True:
    frame += 1

    # TODO: wait/check/handle for Serial activity

    # clear out any old/buffered frames
    for cap in caps.values():
        cap.read()

    # read recent frames
    for i, cap in caps.items():
        _, img = cap.read()
        # save to a file and display in window
        cv2.imwrite(f'output/{frame:06}-{i}.jpeg', img)
        cv2.imshow(f'cap {i}', img)

    # handle GUI events/check for keys
    if cv2.waitKey(1) == 27:
        break

您沒有包含要檢查串行活動的任何實際代碼,但是您應該可以在其中使用任何阻止功能。 串行代碼完成后,它將讀取並丟棄所有攝像機的緩沖幀,然后將后續幀保存到磁盤。 請注意,所有清除操作應同時進行,以便(異步)攝像頭設備可以開始一起傳輸其下一幀,然后在所有設備准備就緒時再次遍歷所有設備以拾取幀

鑒於您上面所寫的內容,我認為這應該是解決問題的合理模板。 當然可以使用multiprocessing ,但是我認為這只會使您在這里所做的事情變得毫無意義。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM