Skip to content

rescale

RescaleT module-attribute

RescaleT = TypeVar('RescaleT', bound='RescaleBase')

Rescale

Rescale(
    clip: VideoNode,
    /,
    height: int | float,
    kernel: KernelT,
    upscaler: ScalerT = ArtCNN,
    downscaler: ScalerT = Hermite(linear=True),
    width: int | float | None = None,
    base_height: int | None = None,
    base_width: int | None = None,
    crop: tuple[LeftCrop, RightCrop, TopCrop, BottomCrop] = CropRel(),
    shift: tuple[TopShift, LeftShift] = (0, 0),
    field_based: FieldBasedT | bool | None = None,
    border_handling: int | BorderHandling = MIRROR,
)

Bases: RescaleBase

Rescale wrapper

Examples usage: Basic 720p rescale:

from vsscale import Rescale
from vskernels import Bilinear

rs = Rescale(clip, 720, Bilinear)
final = rs.upscale

Adding aa and dehalo on doubled clip:

from vsaa import based_aa
from vsdehalo import fine_dehalo

aa = based_aa(rs.doubled, supersampler=False)
dehalo = fine_dehalo(aa, ...)

rs.doubled = dehalo

Loading line_mask and credit_mask:

from vsmasktools import diff_creditless_oped
from vsexprtools import ExprOp

rs.default_line_mask()

oped_credit_mask = diff_creditless_oped(...)
credit_mask = rs.default_credit_mask(thr=0.209, ranges=(200, 300), postfilter=4)
rs.credit_mask = ExprOp.ADD.combine(oped_credit_mask, credit_mask)

Fractionnal rescale:

from vsscale import Rescale
from vskernels import Bilinear

# Forcing the height to a float will ensure a fractionnal descale
rs = Rescale(clip, 800.0, Bilinear)
>>> rs.descale_args
ScalingArgs(
    width=1424, height=800, src_width=1422.2222222222222, src_height=800.0,
    src_top=0.0, src_left=0.8888888888889142, mode='hw'
)

# while doing this will not
rs = Rescale(clip, 800, Bilinear)
>>> rs.descale_args
ScalingArgs(width=1422, height=800, src_width=1422, src_height=800, src_top=0, src_left=0, mode='hw')

Cropping is also supported:

from vsscale import Rescale
from vskernels import Bilinear

# Descaling while cropping the letterboxes at the top and bottom
rs = Rescale(clip, 874, Bilinear, crop=(0, 0, 202, 202))
>>> rs.descale_args
ScalingArgs(
    width=1554, height=548, src_width=1554.0, src_height=547.0592592592592,
    src_top=0.4703703703703752, src_left=0.0, mode='hw'
)

# Same thing but ensuring the width is fractionnal descaled
rs = Rescale(clip, 874.0, Bilinear, crop=(0, 0, 202, 202))
>>> rs.descale_args
ScalingArgs(
    width=1554, height=548, src_width=1553.7777777777778, src_height=547.0592592592592,
    src_top=0.4703703703703752, src_left=0.11111111111108585, mode='hw'
)

Initialize the rescaling process.

Parameters:

  • clip

    (VideoNode) –

    Clip to be rescaled

  • height

    (int | float) –

    Height to be descaled to. Forcing the value to float will ensure a fractionnal descale

  • kernel

    (KernelT) –

    Kernel used for descaling

  • upscaler

    (ScalerT, default: ArtCNN ) –

    Scaler that supports doubling, defaults to ArtCNN

  • downscaler

    (ScalerT, default: Hermite(linear=True) ) –

    Scaler used for downscaling the upscaled clip back to input res, defaults to Hermite(linear=True)

  • width

    (int | float | None, default: None ) –

    Width to be descaled to. If None, automatically calculated from the height

  • base_height

    (int | None, default: None ) –

    Integer height at which the clip will be contained. If None, automatically calculated from the height

  • base_width

    (int | None, default: None ) –

    Integer width at which the clip will be contained. If None, automatically calculated from the width

  • crop

    (tuple[LeftCrop, RightCrop, TopCrop, BottomCrop], default: CropRel() ) –

    Cropping values to apply before descale. The ratio descale height / source height will be preserved even after descale. The cropped area is restored when calling the upscale property.

  • shift

    (tuple[TopShift, LeftShift], default: (0, 0) ) –

    Shifts to apply during descale and upscale, defaults to (0, 0)

  • field_based

    (FieldBasedT | bool | None, default: None ) –

    Parameter specifying the source is a cross-converted/interlaced upscaled content

  • border_handling

    (int | BorderHandling, default: MIRROR ) –

    Adjust the way the clip is padded internally during the scaling process. Accepted values are: 0: Assume the image was resized with mirror padding. 1: Assume the image was resized with zero padding. 2: Assume the image was resized with extend padding, where the outermost row was extended infinitely far. Defaults to 0

Source code
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
def __init__(
    self,
    clip: vs.VideoNode,
    /,
    height: int | float,
    kernel: KernelT,
    upscaler: ScalerT = ArtCNN,
    downscaler: ScalerT = Hermite(linear=True),
    width: int | float | None = None,
    base_height: int | None = None,
    base_width: int | None = None,
    crop: tuple[LeftCrop, RightCrop, TopCrop, BottomCrop] = CropRel(),
    shift: tuple[TopShift, LeftShift] = (0, 0),
    field_based: FieldBasedT | bool | None = None,
    border_handling: int | BorderHandling = BorderHandling.MIRROR
) -> None:
    """Initialize the rescaling process.

    :param clip:                Clip to be rescaled
    :param height:              Height to be descaled to.
                                Forcing the value to float will ensure a fractionnal descale
    :param kernel:              Kernel used for descaling
    :param upscaler:            Scaler that supports doubling, defaults to ArtCNN
    :param downscaler:          Scaler used for downscaling the upscaled clip back to input res,
                                defaults to Hermite(linear=True)
    :param width:               Width to be descaled to. If None, automatically calculated from the height
    :param base_height:         Integer height at which the clip will be contained.
                                If None, automatically calculated from the height
    :param base_width:          Integer width at which the clip will be contained.
                                If None, automatically calculated from the width
    :param crop:                Cropping values to apply before descale.
                                The ratio descale height / source height will be preserved even after descale.
                                The cropped area is restored when calling the `upscale` property.
    :param shift:               Shifts to apply during descale and upscale, defaults to (0, 0)
    :param field_based:         Parameter specifying the source is a cross-converted/interlaced upscaled content
    :param border_handling:     Adjust the way the clip is padded internally during the scaling process.
                                Accepted values are:
                                    0: Assume the image was resized with mirror padding.
                                    1: Assume the image was resized with zero padding.
                                    2: Assume the image was resized with extend padding,
                                       where the outermost row was extended infinitely far.
                                Defaults to 0
    """
    self._line_mask: vs.VideoNode | None = None
    self._credit_mask: vs.VideoNode | None = None
    self._ignore_mask: vs.VideoNode | None = None
    self._crop = crop
    self._pre = clip

    self.descale_args = ScalingArgs.from_args(
        clip, height, width, base_height, base_width, shift[0], shift[1], crop, mode='hw'
    )

    super().__init__(clip, kernel, upscaler, downscaler, field_based, border_handling)

    if self._crop > (0, 0, 0, 0):
        self.clipy = self.clipy.std.Crop(*self._crop)

border_handling instance-attribute

border_handling = BorderHandling(int(border_handling))

chroma instance-attribute

chroma = chroma

clipy instance-attribute

clipy = Crop(*_crop)

credit_mask deletable property writable

credit_mask: VideoNode

descale cached property

descale: VideoNode

descale_args instance-attribute

descale_args = from_args(
    clip,
    height,
    width,
    base_height,
    base_width,
    shift[0],
    shift[1],
    crop,
    mode="hw",
)

doubled cached property

doubled: VideoNode

downscaler instance-attribute

downscaler = ensure_obj(downscaler)

field_based instance-attribute

field_based: FieldBased | None = from_param(field_based)

ignore_mask deletable property writable

ignore_mask: VideoNode

kernel instance-attribute

kernel = ensure_obj(kernel)

line_mask deletable property writable

line_mask: VideoNode

rescale cached property

rescale: VideoNode

upscale cached property

upscale: VideoNode

Returns the upscaled clip

upscaler instance-attribute

upscaler = ensure_obj(upscaler)

default_credit_mask

default_credit_mask(
    rescale: VideoNode | None = None,
    src: VideoNode | None = None,
    thr: float = 0.216,
    expand: int = 4,
    ranges: FrameRangeN | FrameRangesN | None = None,
    exclusive: bool = False,
    **kwargs: Any
) -> VideoNode

Load a credit mask by making a difference mask between src and rescaled clips

Parameters:

  • rescale

    (VideoNode | None, default: None ) –

    Rescaled clip, defaults to rescaled instance clip

  • src

    (VideoNode | None, default: None ) –

    Source clip, defaults to source instance clip

  • thr

    (float, default: 0.216 ) –

    Threshold of the amplification expr, defaults to 0.216

  • expand

    (int, default: 4 ) –

    Additional expand radius applied to the mask, defaults to 4

  • ranges

    (FrameRangeN | FrameRangesN | None, default: None ) –

    If specified, ranges to apply the credit clip to

  • exclusive

    (bool, default: False ) –

    Use exclusive ranges (Default: False)

Returns:

  • VideoNode

    Generated mask

Source code
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
def default_credit_mask(
    self, rescale: vs.VideoNode | None = None, src: vs.VideoNode | None = None,
    thr: float = 0.216, expand: int = 4,
    ranges: FrameRangeN | FrameRangesN | None = None, exclusive: bool = False,
    **kwargs: Any
) -> vs.VideoNode:
    """
    Load a credit mask by making a difference mask between src and rescaled clips

    :param rescale:     Rescaled clip, defaults to rescaled instance clip
    :param src:         Source clip, defaults to source instance clip
    :param thr:         Threshold of the amplification expr, defaults to 0.216
    :param expand:      Additional expand radius applied to the mask, defaults to 4
    :param ranges:      If specified, ranges to apply the credit clip to
    :param exclusive:   Use exclusive ranges (Default: False)
    :return:            Generated mask
    """
    if not src:
        src = self.clipy
    if not rescale:
        rescale = self.rescale

    src, rescale = get_y(src), get_y(rescale)

    credit_mask = based_diff_mask(
        src, rescale, thr=thr, expand=expand, func=self.default_credit_mask, **kwargs
    )

    if ranges is not None:
        credit_mask = replace_ranges(credit_mask.std.BlankClip(keep=True), credit_mask, ranges, exclusive)

    self.credit_mask = credit_mask

    return self.credit_mask

default_line_mask

default_line_mask(
    clip: VideoNode | None = None, scaler: ScalerT = Bilinear, **kwargs: Any
) -> VideoNode

Load a default Kirsch line mask in the class instance. Additionnaly, it is returned.

Parameters:

  • clip

    (VideoNode | None, default: None ) –

    Reference clip, defaults to doubled clip if None.

  • scaler

    (ScalerT, default: Bilinear ) –

    Scaled used for matching the source clip format, defaults to Bilinear

Returns:

  • VideoNode

    Generated mask.

Source code
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
def default_line_mask(
    self, clip: vs.VideoNode | None = None, scaler: ScalerT = Bilinear, **kwargs: Any
) -> vs.VideoNode:
    """
    Load a default Kirsch line mask in the class instance. Additionnaly, it is returned.

    :param clip:    Reference clip, defaults to doubled clip if None.
    :param scaler:  Scaled used for matching the source clip format, defaults to Bilinear
    :return:        Generated mask.
    """
    scaler = Scaler.ensure_obj(scaler)
    scale_kwargs = scaler.kwargs if clip else self.descale_args.kwargs(self.doubled) | scaler.kwargs

    clip = clip if clip else self.doubled

    line_mask = KirschTCanny.edgemask(clip, **kwargs).std.Maximum().std.Minimum()
    line_mask = scaler.scale(line_mask, self.clipy.width, self.clipy.height, format=self.clipy.format, **scale_kwargs)

    self.line_mask = line_mask

    return self.line_mask

RescaleBase

RescaleBase(
    clip: VideoNode,
    /,
    kernel: KernelT,
    upscaler: ScalerT = ArtCNN,
    downscaler: ScalerT = Hermite(linear=True),
    field_based: FieldBasedT | bool | None = None,
    border_handling: int | BorderHandling = MIRROR,
)
Source code
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
def __init__(
    self,
    clip: vs.VideoNode,
    /,
    kernel: KernelT,
    upscaler: ScalerT = ArtCNN,
    downscaler: ScalerT = Hermite(linear=True),
    field_based: FieldBasedT | bool | None = None,
    border_handling: int | BorderHandling = BorderHandling.MIRROR
) -> None:
    assert check_variable(clip, self.__class__)

    self.clipy, *chroma = split(clip)
    self.chroma = chroma

    self.kernel = Kernel.ensure_obj(kernel)
    self.upscaler = Scaler.ensure_obj(upscaler)

    self.downscaler = Scaler.ensure_obj(downscaler)

    self.field_based = FieldBased.from_param(field_based)

    self.border_handling = BorderHandling(int(border_handling))

border_handling instance-attribute

border_handling = BorderHandling(int(border_handling))

chroma instance-attribute

chroma = chroma

descale cached property

descale: VideoNode

descale_args instance-attribute

descale_args: ScalingArgs

doubled cached property

doubled: VideoNode

downscaler instance-attribute

downscaler = ensure_obj(downscaler)

field_based instance-attribute

field_based: FieldBased | None = from_param(field_based)

kernel instance-attribute

kernel = ensure_obj(kernel)

rescale cached property

rescale: VideoNode

upscale cached property

upscale: VideoNode

Returns the upscaled clip

upscaler instance-attribute

upscaler = ensure_obj(upscaler)