MCPcopy Create free account
hub / github.com/Breakthrough/PySceneDetect / HistogramDetector

Class HistogramDetector

scenedetect/detectors/histogram_detector.py:27–172  ·  view source on GitHub ↗

Compares the difference in the Y channel of YUV histograms for adjacent frames. When the difference exceeds a given threshold, a cut is detected.

Source from the content-addressed store, hash-verified

25
26
27class HistogramDetector(SceneDetector):
28 """Compares the difference in the Y channel of YUV histograms for adjacent frames. When the
29 difference exceeds a given threshold, a cut is detected."""
30
31 METRIC_KEYS: ty.ClassVar[list[str]] = ["hist_diff"]
32
33 def __init__(
34 self,
35 threshold: float = 0.05,
36 bins: int = 256,
37 min_scene_len: TimecodeLike = 15,
38 ):
39 """
40 Arguments:
41 threshold: maximum relative difference between 0.0 and 1.0 that the histograms can
42 differ. Histograms are calculated on the Y channel after converting the frame to
43 YUV, and normalized based on the number of bins. Higher differences imply greater
44 change in content, so larger threshold values are less sensitive to cuts.
45 bins: Number of bins to use for the histogram.
46 min_scene_len: Once a cut is detected, this much time must pass before a new one can
47 be added to the scene list. Accepts any :data:`TimecodeLike` value.
48 """
49 super().__init__()
50 # Internally, threshold represents the correlation between two histograms and has values
51 # between -1.0 and 1.0.
52 self._threshold = max(0.0, min(1.0, 1.0 - threshold))
53 self._bins = bins
54 self._min_scene_len = min_scene_len
55 self._last_hist = None
56 self._last_cut = None
57 self._metric_key = f"hist_diff [bins={self._bins}]"
58
59 def process_frame(
60 self, timecode: FrameTimecode, frame_img: numpy.ndarray
61 ) -> list[FrameTimecode]:
62 """Computes the histogram of the luma channel of the frame image and compares it with the
63 histogram of the luma channel of the previous frame. If the difference between the
64 histograms exceeds the threshold, a scene cut is detected.
65 Histogram difference is computed using the correlation metric.
66
67 Arguments:
68 timecode: Timecode of the frame that is being passed.
69 frame_img: Decoded frame image (numpy.ndarray) to perform scene
70 detection on.
71
72 Returns:
73 List of timecodes where scene cuts have been detected. There may be 0
74 or more timecodes in the list, and not necessarily the same as `timecode`.
75 """
76 cut_list = []
77
78 np_data_type = frame_img.dtype
79
80 if np_data_type != numpy.uint8:
81 raise ValueError("Image must be 8-bit rgb for HistogramDetector")
82
83 if frame_img.shape[2] != 3:
84 raise ValueError("Image must have three color channels for HistogramDetector")

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected