From da69117fc5c23f8e631a523a37d95d3de0df7654 Mon Sep 17 00:00:00 2001 From: Askill Date: Sat, 30 Oct 2021 15:17:44 +0200 Subject: [PATCH] added packaging information --- .gitignore | 2 +- src/CV2-Threaded-Video-Capture/VideoReader.py | 132 ++++++++++++++++++ src/CV2-Threaded-Video-Capture/__meta__.py | 3 + 3 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 src/CV2-Threaded-Video-Capture/VideoReader.py create mode 100644 src/CV2-Threaded-Video-Capture/__meta__.py diff --git a/.gitignore b/.gitignore index fbf1f6c..aca6aa1 100644 --- a/.gitignore +++ b/.gitignore @@ -112,7 +112,7 @@ venv/ ENV/ env.bak/ venv.bak/ -src/ + # Spyder project settings .spyderproject .spyproject diff --git a/src/CV2-Threaded-Video-Capture/VideoReader.py b/src/CV2-Threaded-Video-Capture/VideoReader.py new file mode 100644 index 0000000..ae77f69 --- /dev/null +++ b/src/CV2-Threaded-Video-Capture/VideoReader.py @@ -0,0 +1,132 @@ +from queue import Queue + +import cv2 +import threading +import os + +class VideoReader: + listOfFrames = None + w = None + h = None + + def __init__(self, config, setOfFrames=None): + videoPath = config["inputPath"] + self.videoPath = videoPath + + if videoPath is None: + raise Exception("VideoReader:: Video reader needs a videoPath!") + if not os.path.exists(videoPath): + raise Exception("VideoReader:: Provided video path does not exist") + + self.lastFrame = 0 + # buffer data struct: + # buffer = Queue([(frameNumber, frame), ]) + self.buffer = Queue(config["videoBufferLength"]) + self.vc = cv2.VideoCapture(videoPath) + self.stopped = False + self.getWH() + self.calcFPS() + self.calcLength() + self.calcStartTime() + if setOfFrames is not None: + self.listOfFrames = sorted(setOfFrames) + + def __enter__(self): + self.fillBuffer() + return self + + def __exit__(self, type, value, traceback): + self.stop() + + def stop(self): + self.thread.join() + self.vc.release() + + def pop(self): + return self.buffer.get(block=True) + + def fillBuffer(self, listOfFrames=None): + self.endFrame = int(self.vc.get(cv2.CAP_PROP_FRAME_COUNT)) + if listOfFrames is not None: + self.listOfFrames = listOfFrames + + if self.listOfFrames is not None: + self.thread = threading.Thread( + target=self.readFramesByList, args=()) + else: + self.thread = threading.Thread(target=self.readFrames, args=()) + self.thread.start() + + def readFrames(self): + '''Reads video from start to finish''' + while self.lastFrame < self.endFrame: + res, frame = self.vc.read() + if res: + self.buffer.put((self.lastFrame, frame)) + self.lastFrame += 1 + + self.stopped = True + + def readFramesByList(self): + '''Reads all frames from a list of frame numbers''' + self.vc.set(1, self.listOfFrames[0]) + self.lastFrame = self.listOfFrames[0] + self.endFrame = self.listOfFrames[-1] + + while self.lastFrame < self.endFrame: + if self.lastFrame in self.listOfFrames: + res, frame = self.vc.read() + if res: + self.buffer.put((self.lastFrame, frame)) + else: + print("READING FRAMES IS FALSE") + # since the list is sorted the first element is always the lowest relevant framenumber + # [0,1,2,3,32,33,34,35,67,68,69] + self.listOfFrames.pop(0) + self.lastFrame += 1 + else: + # if current Frame number is not in list of Frames, we can skip a few frames + self.vc.set(1, self.listOfFrames[0]) + self.lastFrame = self.listOfFrames[0] + + self.stopped = True + + def videoEnded(self): + if self.stopped and self.buffer.empty(): + return True + else: + return False + + def calcFPS(self): + self.fps = self.vc.get(cv2.CAP_PROP_FPS) + + def getFPS(self): + if self.fps is None: + self.calcFPS() + return self.fps + + def calcLength(self): + fc = int(self.vc.get(cv2.CAP_PROP_FRAME_COUNT)) + self.length = fc / self.getFPS() + + def getLength(self): + if self.length is None: + self.calcLength() + return self.length + + def calcStartTime(self): + starttime = os.stat(self.videoPath).st_mtime + length = self.getLength() + starttime = starttime - length + self.starttime = starttime + + def getStartTime(self): + return self.starttime + + def getWH(self): + '''get width and height''' + if self.w is None or self.h is None: + res, image = self.vc.read() + self.w = image.shape[1] + self.h = image.shape[0] + return (self.w, self.h) diff --git a/src/CV2-Threaded-Video-Capture/__meta__.py b/src/CV2-Threaded-Video-Capture/__meta__.py new file mode 100644 index 0000000..0d43754 --- /dev/null +++ b/src/CV2-Threaded-Video-Capture/__meta__.py @@ -0,0 +1,3 @@ +# Automatically created. Please do not edit. +__version__ = u'1.0.0' +__author__ = u'Patrice Matz'