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
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)