首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何优化Python中的多处理

如何优化Python中的多处理
EN

Stack Overflow用户
提问于 2016-08-10 05:11:53
回答 6查看 4.2K关注 0票数 15

编辑:我有关于视频流是什么的问题,所以我会提供更多的清晰度。该流是从我的网络摄像头的实时视频提要,通过OpenCV访问。我得到的每一帧相机读取它,并将它发送到一个单独的处理过程。该进程根据对图像进行的计算返回文本。然后将文本显示在图像上。我需要实时显示流,如果文本和正在显示的视频之间存在延迟(即,如果文本适用于前一帧,那就可以了)。

也许一个更简单的思考方法是,我正在对摄像头所看到的进行图像识别。我一次发送一个帧到一个单独的进程,对框架进行识别分析,并将文本发回作为一个标题放在实时提要上。显然,处理所需的时间比简单地从摄像头抓取帧并显示出来要花费更多的时间,因此,如果标题和摄像头提要显示的内容出现延迟,这是可以接受的,也是预期的。

现在发生的情况是,由于其他进程,我显示的实时视频是滞后的(当我不向计算过程发送帧时,就不会有任何滞后)。我还确保一次只排队一个帧,这样就避免了队列的重载和延迟。我已经更新了下面的代码以反映这个细节。

我正在使用python中的多处理模块来帮助加快我的主程序。然而,我相信我可能做错了一些事情,因为我不认为计算是并行的。

我希望我的程序从主进程中的视频流中读取图像,并将帧传递给两个子进程,它们对它们进行计算,并将文本发回(包含计算结果)到主进程。

然而,当我使用多重处理时,主进程似乎滞后了,运行速度大约是没有它的一半,这使我相信进程不是完全并行运行的。

在进行了一些研究之后,我推测,延迟可能是由于使用队列在进程之间进行通信(将图像从主程序传递给子进程,并将文本从子进程传递给main)。

但是,我注释掉了计算步骤,只让主进程传递一个图像,子进程返回空白文本,在这种情况下,主进程根本没有减慢。它全速行驶。

所以我相信

1)我没有最优地使用多处理

2)这些进程不能真正并行地运行(我可以理解有一点滞后,但它正在将主进程减半)。

这是我的代码大纲。只有一个消费者,而不是2个,但这两个消费者几乎是一样的。如果有人能提供指导,我将不胜感激。

代码语言:javascript
复制
class Consumer(multiprocessing.Process):

    def __init__(self, task_queue, result_queue):
        multiprocessing.Process.__init__(self)
        self.task_queue = task_queue
        self.result_queue = result_queue
        #other initialization stuff

    def run(self):
        while True:
            image = self.task_queue.get()
            #Do computations on image
            self.result_queue.put("text")

        return

import cv2

tasks = multiprocessing.Queue()
results = multiprocessing.Queue()
consumer = Consumer(tasks,results)
consumer.start()

#Creating window and starting video capturer from camera
cv2.namedWindow("preview")
vc = cv2.VideoCapture(0)
#Try to get the first frame
if vc.isOpened():
    rval, frame = vc.read()
else:
    rval = False

while rval:
    if tasks.empty():
       tasks.put(image)
    else:
       text = tasks.get()
       #Add text to frame
       cv2.putText(frame,text)

    #Showing the frame with all the applied modifications
    cv2.imshow("preview", frame)

    #Getting next frame from camera
    rval, frame = vc.read()
EN

Stack Overflow用户

发布于 2016-08-17 15:59:37

下面是一个更优雅的(IMHO)解决方案,它利用多个进程来处理您的帧:

代码语言:javascript
复制
def process_image(args):
    image, frame = args
    #Do computations on image
    return "text", frame

import cv2

pool = multiprocessing.Pool()

def image_source():
    #Creating window and starting video capturer from camera
    cv2.namedWindow("preview")
    vc = cv2.VideoCapture(0)
    #Try to get the first frame
    if vc.isOpened():
        rval, frame = vc.read()
    else:
        rval = False

    while rval:
        yield image, frame
        # Getting next frame from camera
        rval, frame = vc.read()

for (text, frame) in pool.imap(process_image, image_source()):
    # Add text to frame
    cv2.putText(frame, text)
    # Showing the frame with all the applied modifications
    cv2.imshow("preview", frame)

Pool.imap应该允许您迭代池的结果,而它仍在处理来自您的摄像机的其他图像。

票数 3
EN
查看全部 6 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38864711

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档