Skip to content

abstract

BoundingBox

BoundingBox(
    pos: tuple[int, int] | Position,
    size: tuple[int, int] | Size,
    invert: bool = False,
)

Bases: GeneralMask

Source code
37
38
def __init__(self, pos: tuple[int, int] | Position, size: tuple[int, int] | Size, invert: bool = False) -> None:
    self.pos, self.size, self.invert = Position(pos), Size(size), invert

invert instance-attribute

invert: bool

pos instance-attribute

pos: Position

size instance-attribute

size: Size

apply_mask

apply_mask(
    _clipa: VideoNode,
    _clipb: VideoNode,
    _ref: VideoNode | None = None,
    /,
    **kwargs: Any,
) -> VideoNode
Source code
25
26
27
28
29
@inject_self.init_kwargs.clean
def apply_mask(
    self, _clipa: vs.VideoNode, _clipb: vs.VideoNode, _ref: vs.VideoNode | None = None, /, **kwargs: Any
) -> vs.VideoNode:
    return _clipa.std.MaskedMerge(_clipb, self.get_mask(_ref or _clipa, **kwargs))

get_mask

get_mask(ref: VideoNode, *args: Any, **kwargs: Any) -> VideoNode
Source code
40
41
42
def get_mask(self, ref: vs.VideoNode, *args: Any, **kwargs: Any) -> vs.VideoNode:  # type: ignore[override]
    from .utils import squaremask
    return squaremask(ref, self.size.x, self.size.y, self.pos.x, self.pos.y, self.invert, False, self.get_mask)

DeferredMask

DeferredMask(
    ranges: FrameRangeN | FrameRangesN | None = None,
    bound: BoundingBox | None = None,
    *,
    blur: bool = False,
    refframes: int | list[int | None] | None = None
)

Bases: GeneralMask

Source code
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
def __init__(
    self, ranges: FrameRangeN | FrameRangesN | None = None, bound: BoundingBox | None = None,
    *, blur: bool = False, refframes: int | list[int | None] | None = None
) -> None:
    self.ranges = ranges if isinstance(ranges, Sequence) else [(0, None)] if ranges is None else [ranges]
    self.blur = blur
    self.bound = bound

    if refframes is None:
        self.refframes = []
    else:
        self.refframes = refframes if isinstance(refframes, list) else normalize_seq(refframes, len(self.ranges))

    if len(self.refframes) > 0 and len(self.refframes) != len(self.ranges):
        raise FramesLengthError(
            self.__class__, '', 'Received reference frame and range list size mismatch!'
        )

blur instance-attribute

blur: bool = blur

bound instance-attribute

bound: BoundingBox | None = bound

ranges instance-attribute

ranges: FrameRangesN = (
    ranges
    if isinstance(ranges, Sequence)
    else [(0, None)] if ranges is None else [ranges]
)

refframes instance-attribute

refframes: list[int | None]

apply_mask

apply_mask(
    _clipa: VideoNode,
    _clipb: VideoNode,
    _ref: VideoNode | None = None,
    /,
    **kwargs: Any,
) -> VideoNode
Source code
25
26
27
28
29
@inject_self.init_kwargs.clean
def apply_mask(
    self, _clipa: vs.VideoNode, _clipb: vs.VideoNode, _ref: vs.VideoNode | None = None, /, **kwargs: Any
) -> vs.VideoNode:
    return _clipa.std.MaskedMerge(_clipb, self.get_mask(_ref or _clipa, **kwargs))

get_mask

get_mask(clip: VideoNode, ref: VideoNode, **kwargs: Any) -> VideoNode
Source code
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
@limiter
def get_mask(self, clip: vs.VideoNode, ref: vs.VideoNode, **kwargs: Any) -> vs.VideoNode:
    assert check_variable(clip, self.get_mask)
    assert check_variable(ref, self.get_mask)

    if self.refframes:
        hm = ref.std.BlankClip(
            format=ref.format.replace(color_family=vs.GRAY, subsampling_h=0, subsampling_w=0).id, keep=True
        )

        for ran, rf in zip(self.ranges, self.refframes):
            if rf is None:
                rf = ref.num_frames - 1
            elif rf < 0:
                rf = ref.num_frames - 1 + rf

            mask = depth(
                self._mask(clip[rf], ref[rf], **kwargs), clip,
                range_out=ColorRange.FULL, range_in=ColorRange.FULL
            ).std.Loop(hm.num_frames)

            hm = replace_ranges(hm, ExprOp.MAX.combine(hm, mask), ran)
    else:
        hm = depth(
            self._mask(clip, ref, **kwargs), clip,
            range_out=ColorRange.FULL, range_in=ColorRange.FULL
        )

    if self.bound:
        bm = self.bound.get_mask(hm, **kwargs)

        if self.blur:
            bm = box_blur(bm, 5, 5)

        hm = hm.std.BlankClip(keep=True).std.MaskedMerge(hm, bm)

    return hm

GeneralMask

Bases: ABC

apply_mask

apply_mask(
    _clipa: VideoNode,
    _clipb: VideoNode,
    _ref: VideoNode | None = None,
    /,
    **kwargs: Any,
) -> VideoNode
Source code
25
26
27
28
29
@inject_self.init_kwargs.clean
def apply_mask(
    self, _clipa: vs.VideoNode, _clipb: vs.VideoNode, _ref: vs.VideoNode | None = None, /, **kwargs: Any
) -> vs.VideoNode:
    return _clipa.std.MaskedMerge(_clipb, self.get_mask(_ref or _clipa, **kwargs))

get_mask abstractmethod

get_mask(clip: VideoNode, *args: Any, **kwargs: Any) -> VideoNode
Source code
21
22
23
@abstractmethod
def get_mask(self, clip: vs.VideoNode, *args: Any, **kwargs: Any) -> vs.VideoNode:
    ...