简体   繁体   English

无法启动 python 多处理。处理两次

[英]cannot start a python multiprocessing.Process twice

Below given is my code.下面给出的是我的代码。 I am trying to scan barcodes and display it using OpenCV.我正在尝试使用 OpenCV 扫描条形码并显示它。 The program works well but there is a huge lag in fps when grabbing frames from drone camera as RTMP stream.该程序运行良好,但在从无人机相机抓取帧为 RTMP stream 时,fps 存在巨大滞后。 Due to the same I am trying to use multi processing method.由于同样的原因,我正在尝试使用多处理方法。

import pandas as pd
import cv2
import numpy as np
from pyzbar.pyzbar import decode
from pyzbar.pyzbar import ZBarSymbol
import time 
import multiprocessing 
global frame
def barcode(frame):
    for barcode in decode(frame, symbols=[ZBarSymbol.CODE128]):
        myData = barcode.data.decode('utf-8')
        pts = np.array([barcode.polygon],np.int32)
        pts = pts.reshape((-1,1,2))
        cv2.polylines(frame, [pts], True, (255,0,255),5)
        pts2 = barcode.rect
        akash = []
        akash.append(myData)
        cv2.putText(frame, myData, (pts2[0], pts2[1]), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (255,99,71), 2)

p1 = multiprocessing.Process(target = barcode)        

cv2.namedWindow("Result", cv2.WINDOW_NORMAL)

vid = cv2.VideoCapture(0)
if __name__ == '__main__':
    while(True):
        ret, frame = vid.read()
        if frame is not None:
            p1.start()   
            cv2.imshow('Result',frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
vid.release()
vid.destroyAllWindows()

and the error is错误是

AssertionError                            Traceback (most recent call last)
<ipython-input-1-df50d7c70cda> in <module>
     27         ret, frame = vid.read()
     28         if frame is not None:
---> 29             p1.start()
     30             cv2.imshow('Result',frame)
     31         if cv2.waitKey(1) & 0xFF == ord('q'):

C:\ProgramData\Anaconda3\lib\multiprocessing\process.py in start(self)
    113         '''
    114         self._check_closed()
--> 115         assert self._popen is None, 'cannot start a process twice'
    116         assert self._parent_pid == os.getpid(), \
    117                'can only start a process object created by current process'

AssertionError: cannot start a process twice

Try not to create processes inside loops.尽量不要在循环内创建进程 The best way to use processes is to create n processes outside and then, with the help of Queues , access and push data.使用进程的最佳方式是在外部创建 n 个进程,然后在Queues的帮助下访问和推送数据。

  • In the following code, I created 5 processes which would run infinitely and try to fetch data from inQ queue.在下面的代码中,我创建了 5 个进程,它们将无限运行并尝试从inQ队列中获取数据。
  • Then do all the processing that you were doing.然后做你正在做的所有处理。
  • After that, I'm pushing it to outQ queue, which we'll use later to show the results.之后,我将其推送到outQ队列,稍后我们将使用它来显示结果。
  • In the main, I am simply reading the data from the opencv vid object and the pushing to the inQ which our Processes will use to fetch frame.总的来说,我只是从 opencv vid object中读取数据,然后推送到我们的进程将用来获取帧的 inQ。
  • Next, I'm just fetching the results.接下来,我只是获取结果。 This way appears better to me as we don't have to create processes in every iteration as well as we have multiple processes ready to process the data at all times.这种方式对我来说似乎更好,因为我们不必在每次迭代中都创建流程,而且我们有多个流程随时准备处理数据。 You can also set the buffer limit for the queue if you want.如果需要,您还可以设置队列的缓冲区限制 Also, with live streams, try to have a skipFrame parameter to skip a few frames.此外,对于实时流,请尝试使用skipFrame参数来跳过几帧。 That would boost up the fps.这将提高fps。
import cv2
import numpy as np
from pyzbar.pyzbar import decode
from pyzbar.pyzbar import ZBarSymbol
import time 
from multiprocessing import Process, Queue

inQ = Queue()
outQ = Queue()


def barcode():
    global inQ
    global outQ
    try:
        print("Solving..")
        frame = inQ.get()
        for barcode in decode(frame, symbols=[ZBarSymbol.CODE128]):
            myData = barcode.data.decode('utf-8')
            pts = np.array([barcode.polygon],np.int32)
            pts = pts.reshape((-1,1,2))
            cv2.polylines(frame, [pts], True, (255,0,255),5)
            pts2 = barcode.rect
            akash = []
            akash.append(myData)
            cv2.putText(frame, myData, (pts2[0], pts2[1]), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (255,99,71), 2)

            outQ.put(frame)
    except Exception as e:
        print(e)


for _ in range(5):  # configure yourself      
    Process(target = barcode).start()        

cv2.namedWindow("Result", cv2.WINDOW_NORMAL)


if __name__ == '__main__':
    print("Inside main")
    vid = cv2.VideoCapture(0)
    while vid.isOpened():
        print("While...")
        ret, frame = vid.read()
        if ret:
            try:
                inQ.put(frame)
            except Exception as e:
                print(e)
        try:
            output = outQ.get()
            cv2.imshow("Result", output)
        except Exception as e:
            print(e)

    vid.release()
    vid.destroyAllWindows()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM