forked from alyssajoaquin14/fast-asd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscene_detection.py
72 lines (64 loc) · 2.51 KB
/
scene_detection.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
from pydantic import BaseModel
from typing import List
class Scene(BaseModel):
start_seconds: float
end_seconds: float
start_timecode: str
end_timecode: str
scene_number: int
start_frame: int
end_frame: int
def scene_detection(
video: str,
threshold: float = 27.0,
adaptive_threshold: bool = False,
) -> Scene:
"""
:param video: The video to detect scenes in
:param threshold: Threshold the average change in pixel intensity must exceed to trigger a cut. Only used if adaptive_threshold is False.
:param adaptive_threshold: Whether to use adaptive thresholding, which compares the difference in content between adjacent frames without a fixed threshold, and instead a rolling average of adjacent frame changes. This can help mitigate false detections in situations such as fast camera motions.
:return: A list of scenes
"""
from scenedetect.detectors import ContentDetector, AdaptiveDetector
from scenedetect.scene_manager import SceneManager
from scenedetect.video_manager import VideoManager
import cv2
cap = cv2.VideoCapture(video)
fps = cap.get(cv2.CAP_PROP_FPS)
cap.release()
video_manager = VideoManager([video])
scene_manager = SceneManager()
if adaptive_threshold:
scene_manager.add_detector(AdaptiveDetector())
else:
scene_manager.add_detector(ContentDetector(threshold=threshold))
base_timecode = video_manager.get_base_timecode()
video_manager.set_downscale_factor()
video_manager.start()
scene_manager.detect_scenes(frame_source=video_manager)
scene_list = scene_manager.get_scene_list(base_timecode)
# print("List of scenes obtained:")
scenes = []
for i, scene in enumerate(scene_list):
print(
"Scene %2d: Start %s / Frame %d, End %s / Frame %d"
% (
i + 1,
scene[0].get_timecode(),
scene[0].get_frames(),
scene[1].get_timecode(),
scene[1].get_frames(),
)
)
start_time_in_seconds = scene[0].get_frames() / fps
end_time_in_seconds = scene[1].get_frames() / fps
yield Scene(
start_seconds=start_time_in_seconds,
end_seconds=end_time_in_seconds,
scene_number=i + 1,
start_timecode=scene[0].get_timecode(),
end_timecode=scene[1].get_timecode(),
start_frame=scene[0].get_frames(),
end_frame=scene[1].get_frames()
).dict()
video_manager.release()