Skip to content
Snippets Groups Projects
Commit 821c2a4b authored by Mathieu Beligon's avatar Mathieu Beligon
Browse files

[CV2FrameGenerator] simplify class

parent 04fc0d12
No related branches found
No related tags found
No related merge requests found
...@@ -10,29 +10,21 @@ from polystar.models.image import Image ...@@ -10,29 +10,21 @@ from polystar.models.image import Image
@dataclass @dataclass
class CV2FrameGeneratorABC(FrameGeneratorABC, ABC): class CV2FrameGeneratorABC(FrameGeneratorABC, ABC):
_cap: cv2.VideoCapture = field(init=False, repr=False)
def __enter__(self):
self._cap = cv2.VideoCapture(*self._capture_params())
# self._cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
assert self._cap.isOpened()
self._post_opening_operation()
def __exit__(self, exc_type, exc_val, exc_tb):
self._cap.release()
def generate(self) -> Iterable[Image]: def generate(self) -> Iterable[Image]:
with self: _cap = self._open()
while 1: while 1:
is_open, frame = self._cap.read() is_open, frame = _cap.read()
if not is_open: if not is_open:
return break
yield frame yield frame
_cap.release()
def _open(self) -> cv2.VideoCapture:
_cap = cv2.VideoCapture(*self._capture_params())
_cap.set(cv2.CAP_PROP_BUFFERSIZE, 0)
assert _cap.isOpened()
return _cap
@abstractmethod @abstractmethod
def _capture_params(self) -> Iterable[Any]: def _capture_params(self) -> Iterable[Any]:
pass pass
def _post_opening_operation(self):
pass
import cv2
from dataclasses import dataclass from dataclasses import dataclass
from pathlib import Path from pathlib import Path
from typing import Any, Iterable, Optional from typing import Any, Iterable, Optional
...@@ -18,10 +20,6 @@ class VideoFrameGenerator(CV2FrameGeneratorABC): ...@@ -18,10 +20,6 @@ class VideoFrameGenerator(CV2FrameGeneratorABC):
def _capture_params(self) -> Iterable[Any]: def _capture_params(self) -> Iterable[Any]:
return (str(self.video_path),) return (str(self.video_path),)
def _post_opening_operation(self):
if self.offset_seconds:
self._cap.set(CAP_PROP_POS_FRAMES, self._video_fps * self.offset_seconds - 2)
@memoized_property @memoized_property
def _video_fps(self) -> int: def _video_fps(self) -> int:
streams_info = ffmpeg.probe(str(self.video_path))["streams"] streams_info = ffmpeg.probe(str(self.video_path))["streams"]
...@@ -30,3 +28,9 @@ class VideoFrameGenerator(CV2FrameGeneratorABC): ...@@ -30,3 +28,9 @@ class VideoFrameGenerator(CV2FrameGeneratorABC):
continue continue
return round(eval(stream_info["avg_frame_rate"])) return round(eval(stream_info["avg_frame_rate"]))
raise ValueError(f"No fps found for video {self.video_path.name}") raise ValueError(f"No fps found for video {self.video_path.name}")
def _open(self) -> cv2.VideoCapture:
_cap = super()._open()
if self.offset_seconds:
_cap.set(CAP_PROP_POS_FRAMES, self._video_fps * self.offset_seconds - 2)
return _cap
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment