将视频分成一帧一帧python_python中视频帧的多处理

我是

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程序可以合并来自文件集合的结果,或者从并行管道输入的stdin读取.这种方式意味着处理代码不需要执行它自己的并行性,但它确实需要多次访问输入文件并从中间点开始提取帧. (这也可以扩展到跨多台机器工作而不改变python ……)

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值