![](/img/trans.png)
[英]How multiple multiprocessing queues pass a value from one function to another
[英]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.