mirror of
https://github.com/YaoFANGUK/video-subtitle-remover.git
synced 2026-02-27 06:04:42 +08:00
93 lines
3.7 KiB
Python
93 lines
3.7 KiB
Python
# -*- coding: utf-8 -*-
|
|
#
|
|
# PySceneDetect: Python-Based Video Scene Detector
|
|
# -------------------------------------------------------------------
|
|
# [ Site: https://scenedetect.com ]
|
|
# [ Docs: https://scenedetect.com/docs/ ]
|
|
# [ Github: https://github.com/Breakthrough/PySceneDetect/ ]
|
|
#
|
|
# Copyright (C) 2014-2023 Brandon Castellano <http://www.bcastell.com>.
|
|
# PySceneDetect is licensed under the BSD 3-Clause License; see the
|
|
# included LICENSE file, or visit one of the above pages for details.
|
|
#
|
|
""":class:`MotionDetector`, detects motion events using background subtraction, morphological
|
|
transforms, and thresholding."""
|
|
|
|
# Third-Party Library Imports
|
|
import cv2
|
|
|
|
# PySceneDetect Library Imports
|
|
from scenedetect.scene_detector import SparseSceneDetector
|
|
|
|
|
|
class MotionDetector(SparseSceneDetector):
|
|
"""Detects motion events in scenes containing a static background.
|
|
|
|
Uses background subtraction followed by noise removal (via morphological
|
|
opening) to generate a frame score compared against the set threshold.
|
|
|
|
Attributes:
|
|
threshold: floating point value compared to each frame's score, which
|
|
represents average intensity change per pixel (lower values are
|
|
more sensitive to motion changes). Default 0.5, must be > 0.0.
|
|
num_frames_post_scene: Number of frames to include in each motion
|
|
event after the frame score falls below the threshold, adding any
|
|
subsequent motion events to the same scene.
|
|
kernel_size: Size of morphological opening kernel for noise removal.
|
|
Setting to -1 (default) will auto-compute based on video resolution
|
|
(typically 3 for SD, 5-7 for HD). Must be an odd integer > 1.
|
|
"""
|
|
|
|
def __init__(self, threshold=0.50, num_frames_post_scene=30, kernel_size=-1):
|
|
"""Initializes motion-based scene detector object."""
|
|
# TODO: Requires porting to v0.5 API.
|
|
raise NotImplementedError()
|
|
"""
|
|
self.threshold = float(threshold)
|
|
self.num_frames_post_scene = int(num_frames_post_scene)
|
|
|
|
self.kernel_size = int(kernel_size)
|
|
if self.kernel_size < 0:
|
|
# Set kernel size when process_frame first runs based on
|
|
# video resolution (480p = 3x3, 720p = 5x5, 1080p = 7x7).
|
|
pass
|
|
|
|
self.bg_subtractor = cv2.createBackgroundSubtractorMOG2(
|
|
detectShadows = False )
|
|
|
|
self.last_frame_score = 0.0
|
|
|
|
self.in_motion_event = False
|
|
self.first_motion_frame_index = -1
|
|
self.last_motion_frame_index = -1
|
|
"""
|
|
|
|
def process_frame(self, frame_num, frame_img):
|
|
# TODO.
|
|
"""
|
|
frame_grayscale = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
|
|
masked_frame = self.bg_subtractor.apply(frame_grayscale)
|
|
|
|
kernel = numpy.ones((self.kernel_size, self.kernel_size), numpy.uint8)
|
|
filtered_frame = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)
|
|
|
|
frame_score = numpy.sum(filtered_frame) / float(
|
|
filtered_frame.shape[0] * filtered_frame.shape[1] )
|
|
"""
|
|
return []
|
|
|
|
def post_process(self, frame_num):
|
|
"""Writes the last scene if the video ends while in a motion event.
|
|
"""
|
|
|
|
# If the last fade detected was a fade out, we add a corresponding new
|
|
# scene break to indicate the end of the scene. This is only done for
|
|
# fade-outs, as a scene cut is already added when a fade-in is found.
|
|
"""
|
|
if self.in_motion_event:
|
|
# Write new scene based on first and last motion event frames.
|
|
pass
|
|
return self.in_motion_event
|
|
"""
|
|
return []
|