diff --git a/scenedetect/backends/moviepy.py b/scenedetect/backends/moviepy.py index f41ad196..36473bb8 100644 --- a/scenedetect/backends/moviepy.py +++ b/scenedetect/backends/moviepy.py @@ -22,7 +22,7 @@ import cv2 from moviepy.video.io.ffmpeg_reader import FFMPEG_VideoReader -from numpy import ndarray +import numpy as np from scenedetect.frame_timecode import FrameTimecode from scenedetect.platform import get_file_name @@ -63,8 +63,8 @@ def __init__(self, path: AnyStr, framerate: Optional[float] = None, print_infos: # This will always be one behind self._reader.lastread when we finally call read() # as MoviePy caches the first frame when opening the video. Thus self._last_frame # will always be the current frame, and self._reader.lastread will be the next. - self._last_frame: Union[bool, ndarray] = False - self._last_frame_rgb: Optional[ndarray] = None + self._last_frame: Union[bool, np.ndarray] = False + self._last_frame_rgb: Optional[np.ndarray] = None # Older versions don't track the video position when calling read_frame so we need # to keep track of the current frame number. self._frame_number = 0 @@ -193,15 +193,15 @@ def reset(self): self._frame_number = 0 self._eof = False - def read(self, decode: bool = True, advance: bool = True) -> Union[ndarray, bool]: - """Read and decode the next frame as a numpy.ndarray. Returns False when video ends. + def read(self, decode: bool = True, advance: bool = True) -> Union[np.ndarray, bool]: + """Read and decode the next frame as a np.ndarray. Returns False when video ends. Arguments: decode: Decode and return the frame. advance: Seek to the next frame. If False, will return the current (last) frame. Returns: - If decode = True, the decoded frame (numpy.ndarray), or False (bool) if end of video. + If decode = True, the decoded frame (np.ndarray), or False (bool) if end of video. If decode = False, a bool indicating if advancing to the the next frame succeeded. """ if not advance: diff --git a/scenedetect/backends/opencv.py b/scenedetect/backends/opencv.py index ca9d318c..464a5512 100644 --- a/scenedetect/backends/opencv.py +++ b/scenedetect/backends/opencv.py @@ -24,7 +24,7 @@ import os.path import cv2 -from numpy import ndarray +import numpy as np from scenedetect.frame_timecode import FrameTimecode, MAX_FPS_DELTA from scenedetect.platform import get_file_name @@ -262,8 +262,8 @@ def reset(self): self._cap.release() self._open_capture(self._frame_rate) - def read(self, decode: bool = True, advance: bool = True) -> Union[ndarray, bool]: - """Read and decode the next frame as a numpy.ndarray. Returns False when video ends, + def read(self, decode: bool = True, advance: bool = True) -> Union[np.ndarray, bool]: + """Read and decode the next frame as a np.ndarray. Returns False when video ends, or the maximum number of decode attempts has passed. Arguments: @@ -271,7 +271,7 @@ def read(self, decode: bool = True, advance: bool = True) -> Union[ndarray, bool advance: Seek to the next frame. If False, will return the current (last) frame. Returns: - If decode = True, the decoded frame (numpy.ndarray), or False (bool) if end of video. + If decode = True, the decoded frame (np.ndarray), or False (bool) if end of video. If decode = False, a bool indicating if advancing to the the next frame succeeded. """ if not self._cap.isOpened(): @@ -497,8 +497,8 @@ def reset(self): """Not supported.""" raise NotImplementedError("Reset is not supported.") - def read(self, decode: bool = True, advance: bool = True) -> Union[ndarray, bool]: - """Read and decode the next frame as a numpy.ndarray. Returns False when video ends, + def read(self, decode: bool = True, advance: bool = True) -> Union[np.ndarray, bool]: + """Read and decode the next frame as a np.ndarray. Returns False when video ends, or the maximum number of decode attempts has passed. Arguments: @@ -506,7 +506,7 @@ def read(self, decode: bool = True, advance: bool = True) -> Union[ndarray, bool advance: Seek to the next frame. If False, will return the current (last) frame. Returns: - If decode = True, the decoded frame (numpy.ndarray), or False (bool) if end of video. + If decode = True, the decoded frame (np.ndarray), or False (bool) if end of video. If decode = False, a bool indicating if advancing to the the next frame succeeded. """ if not self._cap.isOpened(): diff --git a/scenedetect/backends/pyav.py b/scenedetect/backends/pyav.py index 9f9f4253..fadace09 100644 --- a/scenedetect/backends/pyav.py +++ b/scenedetect/backends/pyav.py @@ -17,7 +17,7 @@ # pylint: disable=c-extension-no-member import av -from numpy import ndarray +import numpy as np from scenedetect.frame_timecode import FrameTimecode, MAX_FPS_DELTA from scenedetect.platform import get_file_name @@ -261,15 +261,15 @@ def reset(self): except Exception as ex: raise VideoOpenFailure() from ex - def read(self, decode: bool = True, advance: bool = True) -> Union[ndarray, bool]: - """Read and decode the next frame as a numpy.ndarray. Returns False when video ends. + def read(self, decode: bool = True, advance: bool = True) -> Union[np.ndarray, bool]: + """Read and decode the next frame as a np.ndarray. Returns False when video ends. Arguments: decode: Decode and return the frame. advance: Seek to the next frame. If False, will return the current (last) frame. Returns: - If decode = True, the decoded frame (numpy.ndarray), or False (bool) if end of video. + If decode = True, the decoded frame (np.ndarray), or False (bool) if end of video. If decode = False, a bool indicating if advancing to the the next frame succeeded. """ has_advanced = False diff --git a/scenedetect/detectors/adaptive_detector.py b/scenedetect/detectors/adaptive_detector.py index a0154996..bc8dac31 100644 --- a/scenedetect/detectors/adaptive_detector.py +++ b/scenedetect/detectors/adaptive_detector.py @@ -20,7 +20,7 @@ from logging import getLogger from typing import List, Optional -from numpy import ndarray +import numpy as np from scenedetect.detectors import ContentDetector @@ -114,14 +114,14 @@ def stats_manager_required(self) -> bool: """Not required for AdaptiveDetector.""" return False - def process_frame(self, frame_num: int, frame_img: Optional[ndarray]) -> List[int]: + def process_frame(self, frame_num: int, frame_img: Optional[np.ndarray]) -> List[int]: """ Similar to ThresholdDetector, but using the HSV colour space DIFFERENCE instead of single-frame RGB/grayscale intensity (thus cannot detect slow fades with this method). Arguments: frame_num: Frame number of frame that is being passed. - frame_img: Decoded frame image (numpy.ndarray) to perform scene + frame_img: Decoded frame image (np.ndarray) to perform scene detection on. Can be None *only* if the self.is_processing_required() method (inhereted from the base SceneDetector class) returns True. diff --git a/scenedetect/video_manager.py b/scenedetect/video_manager.py index a4ce5cfd..626bfa69 100644 --- a/scenedetect/video_manager.py +++ b/scenedetect/video_manager.py @@ -24,7 +24,7 @@ from logging import getLogger from typing import Iterable, List, Optional, Tuple, Union -from numpy import ndarray +import numpy as np import cv2 from scenedetect.platform import get_file_name @@ -630,14 +630,14 @@ def grab(self) -> bool: self._correct_frame_length() return grabbed - def retrieve(self) -> Tuple[bool, Optional[ndarray]]: + def retrieve(self) -> Tuple[bool, Optional[np.ndarray]]: """ Retrieve (cv2.VideoCapture method) - retrieves and returns a frame. Frame returned corresponds to last call to :meth:`grab()`. Returns: Tuple of (True, frame_image) if a frame was grabbed during the last call to grab(), - and where frame_image is a numpy ndarray of the decoded frame. Otherwise (False, None). + and where frame_image is a numpy np.ndarray of the decoded frame. Otherwise (False, None). """ if not self._started: self.start() @@ -653,7 +653,7 @@ def retrieve(self) -> Tuple[bool, Optional[ndarray]]: self._last_frame = None return (retrieved, self._last_frame) - def read(self, decode: bool = True, advance: bool = True) -> Union[ndarray, bool]: + def read(self, decode: bool = True, advance: bool = True) -> Union[np.ndarray, bool]: """ Return next frame (or current if advance = False), or False if end of video. Arguments: diff --git a/scenedetect/video_stream.py b/scenedetect/video_stream.py index a801e68c..34116be0 100644 --- a/scenedetect/video_stream.py +++ b/scenedetect/video_stream.py @@ -36,7 +36,7 @@ from logging import getLogger from typing import Tuple, Optional, Union -from numpy import ndarray +import numpy as np from scenedetect.frame_timecode import FrameTimecode @@ -178,15 +178,15 @@ def frame_number(self) -> int: # @abstractmethod - def read(self, decode: bool = True, advance: bool = True) -> Union[ndarray, bool]: - """Read and decode the next frame as a numpy.ndarray. Returns False when video ends. + def read(self, decode: bool = True, advance: bool = True) -> Union[np.ndarray, bool]: + """Read and decode the next frame as a np.ndarray. Returns False when video ends. Arguments: decode: Decode and return the frame. advance: Seek to the next frame. If False, will return the current (last) frame. Returns: - If decode = True, the decoded frame (numpy.ndarray), or False (bool) if end of video. + If decode = True, the decoded frame (np.ndarray), or False (bool) if end of video. If decode = False, a bool indicating if advancing to the the next frame succeeded. """ raise NotImplementedError diff --git a/website/pages/changelog.md b/website/pages/changelog.md index dae45a3c..4069a1a7 100644 --- a/website/pages/changelog.md +++ b/website/pages/changelog.md @@ -13,6 +13,7 @@ Releases **API Changes:** - [bugfix] Fix `AttributeError` thrown when accessing `aspect_ratio` on certain videos using `VideoStreamAv` [#355](https://github.com/Breakthrough/PySceneDetect/issues/355) + - [bugfix] Fix circular imports due to partially initialized module for some development environments [#350](https://github.com/Breakthrough/PySceneDetect/issues/350) ### 0.6.2 (July 23, 2023)