python - python中视频帧的多处理

标签 python multiprocessing

我是 python 多处理的新手。我想从一小时长的视频文件的每一帧中提取特征。处理每一帧大约需要 30 毫秒。我认为多处理是个好主意,因为每个帧的处理都独立于所有其他帧。

我想将特征提取的结果存储在自定义类中。

我阅读了一些示例并最终按照建议使用了多处理和队列 here .结果令人失望,现在每帧处理大约需要 1000 毫秒。我猜我产生了大量开销。

是否有更有效的方法来并行处理帧并收集结果?

为了说明,我整理了一个虚拟示例。

import multiprocessing as mp
from multiprocessing import Process, Queue
import numpy as np
import cv2

def main():
    #path='path\to\some\video.avi'
    coordinates=np.random.random((1000,2))
    #video = cv2.VideoCapture(path)
    listOf_FuncAndArgLists=[]

    for i in range(50):
        #video.set(cv2.CAP_PROP_POS_FRAMES,i)
        #img_frame_original = video.read()[1]
        #img_frame_original=cv2.cvtColor(img_frame_original, cv2.COLOR_BGR2GRAY)
        img_frame_dummy=np.random.random((300,300)) #using dummy image for this example
        frame_coordinates=coordinates[i,:]
        listOf_FuncAndArgLists.append([parallel_function,frame_coordinates,i,img_frame_dummy])

    queues=[Queue() for fff in listOf_FuncAndArgLists] #create a queue object for each function
    jobs = [Process(target=storeOutputFFF,args=[funcArgs[0],funcArgs[1:],queues[iii]]) for iii,funcArgs in enumerate(listOf_FuncAndArgLists)]
    for job in jobs: job.start() # Launch them all
    for job in jobs: job.join() # Wait for them all to finish
    # And now, collect all the outputs:
    return([queue.get() for queue in queues])         

def storeOutputFFF(fff,theArgs,que): #add a argument to function for assigning a queue
    print 'MULTIPROCESSING: Launching %s in parallel '%fff.func_name
    que.put(fff(*theArgs)) #we're putting return value into queue

def parallel_function(frame_coordinates,i,img_frame_original):
    #do some image processing that takes about 20-30 ms
    dummyResult=np.argmax(img_frame_original)
    return(resultClass(dummyResult,i))

class resultClass(object):
    def __init__(self,maxIntensity,i):
        self.maxIntensity=maxIntensity
        self.i=i

if __name__ == '__main__':
    mp.freeze_support()
    a=main()
    [x.maxIntensity for x in a]

最佳答案

(常规)python 中的并行处理有点痛苦:在其他语言中,我们只使用线程,但 GIL 使这个成为问题,并且使用多处理在移动数据方面有很大的开销。我发现细粒度的并行性(相对)很难做到,而在单个进程中处理需要 10 秒(或更多)才能处理的“大块”工作可能会更直接。

如果您使用的是 UNIXy 系统,并行处理您的问题的一个更简单的途径是制作一个 python 程序,该程序处理命令行上指定的一段视频(即开始的帧号,以及要处理的帧数),然后使用 GNU parallel一次处理多个片段的工具。第二个 python 程序可以合并文件集合的结果,或者从标准输入读取,从 parallel 管道传输。这种方式意味着处理代码不需要执行它自己的并行性,但它确实需要对输入文件进行多次访问并从中点开始提取帧。 (这也可以扩展为在不更改 python 的情况下跨多台机器工作...)

如果您需要纯 Python 解决方案,可以以类似的方式使用 multiprocessing.Pool.map:映射元组列表(例如,(file, startframe, endframe )) 然后在函数中打开文件并处理该段。

关于python - python中视频帧的多处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38203239/

相关文章:

kubernetes - 在 Kubernetes 中,我们还需要多进程/gunicorn 吗?

Python多处理: print() inside apply_async()

multithreading - 在 cython 中并行化 for 循环 : beyond prange

Python:随着时间的推移将相同的对象分配给相同的标签

python - 在 Keras 中向后传播?

python - Blender3D 中更高效的 Python 脚本

python - 如何对一维 numpy 数组进行下采样?

python - Tox、lib、lib64 和站点包

locking - 多个进程之间共享套接字的accept()(基于Apache preforking)

.net - 如何实现单例 .NET 组件以供多个进程使用?