videoPlayerThreading
is my own made library to basically making 2 class with each using threading to get and show frames. objDect
is also my own library to basically return frame after object detection. I got EOFError : Ran out of Input
error and from the traceback I think it is caused by the multiprocessing itself hence I don’t post my library because it is so long. Can anyone help me with what is wrong with it? Thank you
from multiprocessing import Process import sys import videoPlayerThreading as vpt from objDect import objDect as od def main(videoSource): obd = od( videoSources = videoSource ) getFrame = vpt.getFrames(videoSource).start() showFrame = vpt.showFrames(videoSource).start() while True: frame = getFrame.frame frame=Process(target=obd.predictYolo, args=(frame,)).start() showFrame.frame = frame if getFrame.doVideo == False or showFrame.doVideo == False: getFrame.stop() showFrame.stop() sys.exit() if __name__=="__main__": main(0)
Edit :
Here is the show frames and get frames class it basically only get and show frame using threading.
class getFrames(): def __init__(self, videoSource:Union[int,str]=0): self.stream = self.videoInit(videoSource) self.hasFrame, self.frame = self.stream.read() self.doVideo = True def videoInit(self, videoSource:Union[int,str]): try: cap = cv2.VideoCapture(videoSource) except Exception as e: raise Exception(f"Video source error: {e}") return cap def start(self): Thread(target=self.getFrames, args=()).start() return self def getFrames(self): while self.doVideo: if not self.hasFrame: self.stop() else: (self.hasFrame, self.frame) = self.stream.read() def stop(self): self.doVideo = False self.stream.release() class showFrames(): def __init__(self, frame:cv2=None): self.frame = frame self.doVideo = True def start(self): Thread(target=self.showFrame, args=()).start() return self def showFrame(self): while self.doVideo: cv2.imshow("Video", self.frame) if cv2.waitKey(1) == ord("q"): self.doVideo = False def stop(self): self.doVideo = False
Advertisement
Answer
The best I can understand your program logic you need something like the following. Generator function read_frames
(which may or may not need correction), reads the frames one by one yielding each frame. The main process creates a multiprocessing pool and passes each input frame to the multiprocessing pool to be processed by obd.predictYolo
and sets vpt.frame
with the returned frame. This continues until either there are no more frames to process or showFrame.doVideo
is False
. In short, I have done away with your getFrames
class, which is useless here.
I do not have OpenCV installed and do not really know the package nor do I have your video file, so consider this a starting point for your further investigation.
from multiprocessing.pool import Pool import sys import videoPlayerThreading as vpt from objDect import objDect as od def read_frames(videoSource:Union[int,str]=0): try: stream = cv2.VideoCapture(videoSource) except Exception as e: raise Exception(f"Video source error: {e}") while True: hasFrame, frame = stream.read() if not hasFrame: break yield frame def main(videoSource): obd = od( videoSources = videoSource ) showFrame = vpt.showFrames(videoSource).start() with Pool() as pool: for frame in pool.imap(obd.predictYolo, read_frames(videoSource)): showFrame.frame = frame if showFrame.doVideo is False: showFrame.stop() break if __name__=="__main__": main(0)