multithreading - how to get frames from video in parallel using cv2 & multiprocessing in python -


i've been working cv2 & multiprocessing in python, , have working script stuff individual frames once in input queue. however, wanted speed getting frames queue in first place using multiple cores, tried use same multiprocessing approach read each image queue. can't seem work though, , i'm not sure why. thought maybe because trying write 1 queue, split up, i'm wondering if it's because i'm trying read same video file @ same time.

here hoping accomplish in pseudocode:

for process in range(processcount):     start process this:         frame in range(startframe,endframe):             set next frame startframe             read frame             add frame queue 

here current code. i've tried using pool & separate processes, i'm sticking separate processes because i'm not sure if problem queue management. if call getframe manually, right stuff queue, think function works okay.

i'm sure i'm doing silly (or odd). can suggest solution? great have 1 queue well... had 2 try break down problem.

thanks in advance.

import numpy np import cv2 import multiprocessing mp import time  def getframe(queue, startframe, endframe):     frame in range(startframe, endframe):         cap.set(1,frame)         frameno = int(cap.get(0))         ret, frame = cap.read()         queue.put((frameno,frame))  file = 'video.mov' cap = cv2.videocapture(file) filelen = int(cap.get(7))  # cpucount processcount processcount = mp.cpu_count()/3  inq1 = mp.joinablequeue()  # not sure if right queue type, tried mp.queue() inq2 = mp.joinablequeue() qlist = [inq1,inq2]  # set bunches bunches = [] startframe in range(0,filelen,filelen/processcount):     endframe = startframe + filelen/processcount     bunches.append((startframe,endframe))  getframes = [] in range(processcount):     getframes.append(mp.process(target=getframe, args=(qlist[i], bunches[i][0],bunches[i][1],)))  process in getframes:     process.start()  results1 = [inq1.get() p in range(bunches[0][0],bunches[0][1])] results2 = [inq2.get() p in range(bunches[1][0],bunches[1][1])]  inq1.close() inq2.close() cap.release()  process in getframes:     process.terminate()     process.join() 

there indeed mistake in code : the use of same videocapture object across processes. there's conflict on position being read in file.

this being said, when trying instantiate 1 videocapture per process, interpreter crashes (tested python3.4.2 + opencv3.0.0-beta, , python2.7.6 + opencv2.4.8). here's try far if want check / go further.

import cv2 import multiprocessing mp  def getframe(queue, startframe, endframe):     cap = cv2.videocapture(file)  # crashes here     print("opened capture {}".format(mp.current_process()))     frame in range(startframe, endframe):         # cap.set(cv2.cap_prop_pos_frames, frame)  # opencv3                     cap.set(cv2.cv.cv_cap_prop_pos_frames, frame)         # frameno = int(cap.get(cv2.cap_prop_pos_frames))  # opencv3         frameno = int(cap.get(cv2.cv.cv_cap_prop_pos_frames))         ret, f = cap.read()         if ret:             print("{} - put ({})".format(mp.current_process(), frameno))             queue.put((frameno, f))     cap.release()  file = "video.mov" capture_temp = cv2.videocapture(file) # filelen = int((capture_temp).get(cv2.cap_prop_frame_count))  # opencv3 filelen = int((capture_temp).get(cv2.cv.cv_cap_prop_frame_count)) capture_temp.release()  # cpucount processcount # processcount = mp.cpu_count() / 3 processcount = 2  inq1 = mp.joinablequeue()  # not sure if right queue type, tried mp.queue() inq2 = mp.joinablequeue() qlist = [inq1, inq2]  # set bunches bunches = [] startframe in range(0, filelen, int(filelen / processcount)):     endframe = startframe + int(filelen / processcount)     bunches.append((startframe, endframe))  getframes = [] in range(processcount):     getframes.append(mp.process(target=getframe, args=(qlist[i], bunches[i][0], bunches[i][1])))  process in getframes:     process.start()  results1 = [inq1.get() p in range(bunches[0][0], bunches[0][1])] results2 = [inq2.get() p in range(bunches[1][0], bunches[1][1])]  inq1.close() inq2.close()  process in getframes:     process.terminate()     process.join() 

Comments

Popular posts from this blog

java - Oracle EBS .ClassNotFoundException: oracle.apps.fnd.formsClient.FormsLauncher.class ERROR -

c# - how to use buttonedit in devexpress gridcontrol -

nvd3.js - angularjs-nvd3-directives setting color in legend as well as in chart elements -