Module dvt.aggregate
Aggregators.
Expand source code
# -*- coding: utf-8 -*-
"""Aggregators.
"""
from pandas import DataFrame
class CutAggregator:
"""Uses difference between successive frames to detect cuts.
This aggregator uses information from the difference annotator to detect
the cuts.
Attributes:
min_len (int): minimum allowed length of a cut.
ignore_vals (dict): Dictionary of cutoffs that cause a frame to be
ignored for the purpose of detecting cuts. Keys indicate the
variables in the differences output and values show the minimum
value allowed for a frame to be considered for a cut. Typically
used to ignore frames that are too dark (i.e., during fades). Set
to None (default) if no ignored values are needed.
cut_vals (dict): Dictionary of cutoffs that cause a frame to be
considered a cut. Keys indicate the variables in the differences
output and values are the cutoffs. Setting to None (default) will
return no cuts.
name (str): A description of the aggregator. Used as a key in the
output data.
"""
def __init__(self, **kwargs):
self.ignore_vals = kwargs.get("ignore_vals", {})
self.cut_vals = kwargs.get("cut_vals", None)
self.min_len = kwargs.get("min_len", 1)
def aggregate(self, diff):
"""Aggregate difference annotator.
Args:
diff (DataFrame): output of the difference annotator
Returns:
A dictionary frame giving the detected cuts.
"""
# grab the data, initialize counters, and create output `cuts`
ignore_this_frame = True
current_cut_start = 0
cuts = {"frame_start": [], "frame_end": []}
# cycle through frames and collection shots; assumes that the data is
# ordered by frame
mlen = len(diff["frame"])
for ind in range(mlen):
this_frame = diff["frame"][ind]
# check to see if we should ignore the next frame; by default we
# ignore the phantom frame at the end of the video at time T+1.
ignore_next_frame = False
if (ind + 1) >= mlen:
ignore_next_frame = True
else:
for key, coff in self.ignore_vals.items():
if diff[key][ind + 1] < coff: # pragma: no cover
ignore_next_frame = True
break
# check if there should be a cut; note: this is defined such that
# the this_frame is the *last* frame in the current cut, not the
# first in the next cut
long_flag = (this_frame - current_cut_start + 1) >= self.min_len
if long_flag and not ignore_next_frame:
cut_detect = True
for key, coff in self.cut_vals.items():
if diff[key][ind] < coff:
cut_detect = False
break
else:
cut_detect = False
if ignore_next_frame and not ignore_this_frame:
cut_detect = True
# if `cut_detect` at this point, then we want to finish the active
# cut with the current frame
if cut_detect:
cuts["frame_start"].append(current_cut_start)
cuts["frame_end"].append(this_frame)
if cut_detect or ignore_next_frame:
current_cut_start = this_frame + 1
# push forward the ignore flag
ignore_this_frame = ignore_next_frame
return DataFrame(cuts)
Classes
class CutAggregator (**kwargs)
-
Uses difference between successive frames to detect cuts.
This aggregator uses information from the difference annotator to detect the cuts.
Attributes
min_len
:int
- minimum allowed length of a cut.
ignore_vals
:dict
- Dictionary of cutoffs that cause a frame to be ignored for the purpose of detecting cuts. Keys indicate the variables in the differences output and values show the minimum value allowed for a frame to be considered for a cut. Typically used to ignore frames that are too dark (i.e., during fades). Set to None (default) if no ignored values are needed.
cut_vals
:dict
- Dictionary of cutoffs that cause a frame to be considered a cut. Keys indicate the variables in the differences output and values are the cutoffs. Setting to None (default) will return no cuts.
name
:str
- A description of the aggregator. Used as a key in the output data.
Expand source code
class CutAggregator: """Uses difference between successive frames to detect cuts. This aggregator uses information from the difference annotator to detect the cuts. Attributes: min_len (int): minimum allowed length of a cut. ignore_vals (dict): Dictionary of cutoffs that cause a frame to be ignored for the purpose of detecting cuts. Keys indicate the variables in the differences output and values show the minimum value allowed for a frame to be considered for a cut. Typically used to ignore frames that are too dark (i.e., during fades). Set to None (default) if no ignored values are needed. cut_vals (dict): Dictionary of cutoffs that cause a frame to be considered a cut. Keys indicate the variables in the differences output and values are the cutoffs. Setting to None (default) will return no cuts. name (str): A description of the aggregator. Used as a key in the output data. """ def __init__(self, **kwargs): self.ignore_vals = kwargs.get("ignore_vals", {}) self.cut_vals = kwargs.get("cut_vals", None) self.min_len = kwargs.get("min_len", 1) def aggregate(self, diff): """Aggregate difference annotator. Args: diff (DataFrame): output of the difference annotator Returns: A dictionary frame giving the detected cuts. """ # grab the data, initialize counters, and create output `cuts` ignore_this_frame = True current_cut_start = 0 cuts = {"frame_start": [], "frame_end": []} # cycle through frames and collection shots; assumes that the data is # ordered by frame mlen = len(diff["frame"]) for ind in range(mlen): this_frame = diff["frame"][ind] # check to see if we should ignore the next frame; by default we # ignore the phantom frame at the end of the video at time T+1. ignore_next_frame = False if (ind + 1) >= mlen: ignore_next_frame = True else: for key, coff in self.ignore_vals.items(): if diff[key][ind + 1] < coff: # pragma: no cover ignore_next_frame = True break # check if there should be a cut; note: this is defined such that # the this_frame is the *last* frame in the current cut, not the # first in the next cut long_flag = (this_frame - current_cut_start + 1) >= self.min_len if long_flag and not ignore_next_frame: cut_detect = True for key, coff in self.cut_vals.items(): if diff[key][ind] < coff: cut_detect = False break else: cut_detect = False if ignore_next_frame and not ignore_this_frame: cut_detect = True # if `cut_detect` at this point, then we want to finish the active # cut with the current frame if cut_detect: cuts["frame_start"].append(current_cut_start) cuts["frame_end"].append(this_frame) if cut_detect or ignore_next_frame: current_cut_start = this_frame + 1 # push forward the ignore flag ignore_this_frame = ignore_next_frame return DataFrame(cuts)
Methods
def aggregate(self, diff)
-
Aggregate difference annotator.
Args
diff
:DataFrame
- output of the difference annotator
Returns
A dictionary frame giving the detected cuts.
Expand source code
def aggregate(self, diff): """Aggregate difference annotator. Args: diff (DataFrame): output of the difference annotator Returns: A dictionary frame giving the detected cuts. """ # grab the data, initialize counters, and create output `cuts` ignore_this_frame = True current_cut_start = 0 cuts = {"frame_start": [], "frame_end": []} # cycle through frames and collection shots; assumes that the data is # ordered by frame mlen = len(diff["frame"]) for ind in range(mlen): this_frame = diff["frame"][ind] # check to see if we should ignore the next frame; by default we # ignore the phantom frame at the end of the video at time T+1. ignore_next_frame = False if (ind + 1) >= mlen: ignore_next_frame = True else: for key, coff in self.ignore_vals.items(): if diff[key][ind + 1] < coff: # pragma: no cover ignore_next_frame = True break # check if there should be a cut; note: this is defined such that # the this_frame is the *last* frame in the current cut, not the # first in the next cut long_flag = (this_frame - current_cut_start + 1) >= self.min_len if long_flag and not ignore_next_frame: cut_detect = True for key, coff in self.cut_vals.items(): if diff[key][ind] < coff: cut_detect = False break else: cut_detect = False if ignore_next_frame and not ignore_this_frame: cut_detect = True # if `cut_detect` at this point, then we want to finish the active # cut with the current frame if cut_detect: cuts["frame_start"].append(current_cut_start) cuts["frame_end"].append(this_frame) if cut_detect or ignore_next_frame: current_cut_start = this_frame + 1 # push forward the ignore flag ignore_this_frame = ignore_next_frame return DataFrame(cuts)