Skip to content

bm3d

This module implements wrappers for BM3D

Classes:

AbstractBM3D

AbstractBM3D(
    clip: VideoNode,
    sigma: SingleOrArr[float] = 0.5,
    tr: SingleOrArr[int] | None = None,
    profile: Profile | Config = FAST,
    ref: VideoNode | None = None,
    refine: int = 1,
    matrix: MatrixT | None = None,
    range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None,
    fp32: bool = True,
    *,
    radius: SingleOrArr[int] | MissingT = MISSING
)

Bases: vs_object

Abstract BM3D-based denoiser interface.

Parameters:

  • clip

    (VideoNode) –

    Source clip.

  • sigma

    (SingleOrArr[float], default: 0.5 ) –

    Strength of denoising, valid range is [0, +inf].

  • tr

    (SingleOrArr[int] | None, default: None ) –

    Temporal radius, valid range is [1, 16].

  • profile

    (Profile | Config, default: FAST ) –

    Preset profile. See :py:attr:vsdenoise.bm3d.Profile. Default: Profile.FAST.

  • ref

    (VideoNode | None, default: None ) –

    Reference clip used in block-matching, replacing the basic estimation. If not specified, the input clip is used instead. Default: None.

  • refine

    (int, default: 1 ) –

    The number of times to refine the estimation. * 1 means basic estimate with one final estimate. * n means basic estimate refined with final estimate applied n times. Default: 1.

  • matrix

    (MatrixT | None, default: None ) –

    Enum for the matrix of the input clip. See :py:attr:vstools.enums.Matrix for more info. If not specified, gets the matrix from the "_Matrix" prop of the clip unless it's an RGB clip, in which case it stays as None.

  • range_in

    (ColorRangeT | None, default: None ) –

    Enum for the color range of the input clip. See :py:attr:vstools.enums.ColorRange for more info. If not specified, gets the color from the "_ColorRange" prop of the clip. This check is not performed if the input clip is float.

Methods:

  • basic

    Retrieve the "basic" clip, typically used as a ref clip for :py:attr:final.

  • denoise
  • final

    Retrieve the "final" clip.

Attributes:

Source code
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
def __init__(
    self, clip: vs.VideoNode, sigma: SingleOrArr[float] = 0.5, tr: SingleOrArr[int] | None = None,
    profile: Profile | Profile.Config = Profile.FAST, ref: vs.VideoNode | None = None, refine: int = 1,
    matrix: MatrixT | None = None, range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None, fp32: bool = True, *, radius: SingleOrArr[int] | MissingT = MISSING
) -> None:
    """
    :param clip:            Source clip.
    :param sigma:           Strength of denoising, valid range is [0, +inf].
    :param tr:              Temporal radius, valid range is [1, 16].
    :param profile:         Preset profile. See :py:attr:`vsdenoise.bm3d.Profile`.
                            Default: Profile.FAST.
    :param ref:             Reference clip used in block-matching, replacing the basic estimation.
                            If not specified, the input clip is used instead.
                            Default: None.
    :param refine:          The number of times to refine the estimation.
                             * 1 means basic estimate with one final estimate.
                             * n means basic estimate refined with final estimate applied n times.

                            Default: 1.
    :param matrix:          Enum for the matrix of the input clip.
                            See :py:attr:`vstools.enums.Matrix` for more info.
                            If not specified, gets the matrix from the "_Matrix" prop of the clip
                            unless it's an RGB clip, in which case it stays as `None`.
    :param range_in:        Enum for the color range of the input clip.
                            See :py:attr:`vstools.enums.ColorRange` for more info.
                            If not specified, gets the color from the "_ColorRange" prop of the clip.
                            This check is not performed if the input clip is float.
    """

    assert check_variable(clip, self.__class__)
    assert check_progressive(clip, self.__class__)

    self.sigma = self._Sigma(*normalize_seq(sigma, 3))
    self.tr = self._TemporalRadius(*normalize_seq(tr or 0, 2))

    _is_gray = clip.format.color_family == vs.GRAY

    if _is_gray:
        self.sigma = self.sigma._replace(u=0, v=0)
    elif sum(self.sigma[1:]) == 0:
        _is_gray = True

    if _is_gray:
        colorspace = Colorspace.GRAY
    elif colorspace is None:
        colorspace = Colorspace.OPP_BM3D

    matrix = Matrix.from_param(matrix)

    self.cspconfig = BM3DColorspaceConfig(colorspace, clip, matrix, self.sigma.y == 0, fp32)

    self.cspconfig.clip = self.cspconfig.check_clip(clip, matrix, range_in, self.__class__)

    self.profile = profile if isinstance(profile, ProfileBase.Config) else profile()
    self.ref = self.cspconfig.check_clip(ref, matrix, range_in, self.__class__)
    if refine < 1:
        raise CustomIndexError('"refine" must be >= 1!', self.__class__)

    self.refine = refine

    self.basic_args = {}
    self.final_args = {}

    self.__post_init__()

basic_args instance-attribute

basic_args: KwargsT = {}

Custom kwargs passed to bm3d for the :py:attr:basic clip.

cspconfig instance-attribute

cspconfig: BM3DColorspaceConfig = BM3DColorspaceConfig(
    colorspace, clip, matrix, y == 0, fp32
)

final_args instance-attribute

final_args: KwargsT = {}

Custom kwargs passed to bm3d for the :py:attr:final clip.

profile instance-attribute

profile: Config = profile if isinstance(profile, Config) else profile()

ref instance-attribute

ref: VideoNode | None = check_clip(ref, matrix, range_in, __class__)

refine instance-attribute

refine: int = refine

sigma instance-attribute

sigma: _Sigma = _Sigma(*normalize_seq(sigma, 3))

tr instance-attribute

tr: _TemporalRadius = _TemporalRadius(*normalize_seq(tr or 0, 2))

wclip instance-attribute

wclip: VideoNode

basic abstractmethod

basic(clip: VideoNode, opp: bool = False) -> VideoNode

Retrieve the "basic" clip, typically used as a ref clip for :py:attr:final.

Parameters:

  • clip

    (VideoNode) –

    OPP or GRAY colorspace clip to be processed.

Returns:

  • VideoNode

    Denoised clip to be used as ref.

Source code
376
377
378
379
380
381
382
383
384
@abstractmethod
def basic(self, clip: vs.VideoNode, opp: bool = False) -> vs.VideoNode:
    """
    Retrieve the "basic" clip, typically used as a `ref` clip for :py:attr:`final`.

    :param clip:    OPP or GRAY colorspace clip to be processed.

    :return:        Denoised clip to be used as `ref`.
    """

denoise classmethod

denoise(
    clip: VideoNode,
    sigma: SingleOrArr[float] = 0.5,
    tr: SingleOrArr[int] | None = None,
    refine: int = 1,
    profile: Profile | Config = FAST,
    ref: VideoNode | None = None,
    matrix: MatrixT | None = None,
    range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None,
    fp32: bool = True,
    planes: PlanesT = None,
    **kwargs: Any
) -> VideoNode
Source code
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
@classmethod
def denoise(
    cls, clip: vs.VideoNode, sigma: SingleOrArr[float] = 0.5, tr: SingleOrArr[int] | None = None,
    refine: int = 1, profile: Profile | Profile.Config = Profile.FAST, ref: vs.VideoNode | None = None,
    matrix: MatrixT | None = None, range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None, fp32: bool = True, planes: PlanesT = None, **kwargs: Any
) -> vs.VideoNode:
    func = FunctionUtil(clip, cls.denoise, planes)

    sigma = func.norm_seq(sigma, 0)

    ref = get_y(ref) if func.luma_only and ref else ref

    bm3d = cls(func.work_clip, sigma, tr, profile, ref, refine, matrix, range_in, colorspace, fp32, **kwargs)

    if refine:
        denoise = bm3d.final()
    else:
        denoise = bm3d.basic(
            bm3d.cspconfig.get_clip(bm3d.cspconfig.clip, bm3d._pre_clip, None)
        )

    return func.return_clip(denoise)

final abstractmethod

final(
    clip: VideoNode | None = None,
    ref: VideoNode | None = None,
    refine: int | None = None,
) -> VideoNode

Retrieve the "final" clip.

Parameters:

  • clip

    (VideoNode | None, default: None ) –

    OPP or GRAY colorspace clip to be processed.

  • ref

    (VideoNode | None, default: None ) –

    Reference clip used for weight calculations.

Returns:

  • VideoNode

    Final, refined, denoised clip.

Source code
386
387
388
389
390
391
392
393
394
395
396
397
@abstractmethod
def final(
    self, clip: vs.VideoNode | None = None, ref: vs.VideoNode | None = None, refine: int | None = None
) -> vs.VideoNode:
    """
    Retrieve the "final" clip.

    :param clip:    OPP or GRAY colorspace clip to be processed.
    :param ref:     Reference clip used for weight calculations.

    :return:        Final, refined, denoised clip.
    """

AbstractBM3DCuda

AbstractBM3DCuda(
    clip: VideoNode,
    sigma: SingleOrArr[float] = 0.5,
    tr: SingleOrArr[int] | None = None,
    profile: Profile | Config = FAST,
    ref: VideoNode | None = None,
    refine: int = 1,
    matrix: MatrixT | None = None,
    range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None,
    fp32: bool = True,
    *,
    radius: SingleOrArr[int] | MissingT = MISSING
)

Bases: AbstractBM3D

BM3D implementation by WolframRhodium.

Parameters:

  • clip

    (VideoNode) –

    Source clip.

  • sigma

    (SingleOrArr[float], default: 0.5 ) –

    Strength of denoising, valid range is [0, +inf].

  • tr

    (SingleOrArr[int] | None, default: None ) –

    Temporal radius, valid range is [1, 16].

  • profile

    (Profile | Config, default: FAST ) –

    Preset profile. See :py:attr:vsdenoise.bm3d.Profile. Default: Profile.FAST.

  • ref

    (VideoNode | None, default: None ) –

    Reference clip used in block-matching, replacing the basic estimation. If not specified, the input clip is used instead. Default: None.

  • refine

    (int, default: 1 ) –

    The number of times to refine the estimation. * 1 means basic estimate with one final estimate. * n means basic estimate refined with final estimate applied n times. Default: 1.

  • matrix

    (MatrixT | None, default: None ) –

    Enum for the matrix of the input clip. See :py:attr:vstools.enums.Matrix for more info. If not specified, gets the matrix from the "_Matrix" prop of the clip unless it's an RGB clip, in which case it stays as None.

  • range_in

    (ColorRangeT | None, default: None ) –

    Enum for the color range of the input clip. See :py:attr:vstools.enums.ColorRange for more info. If not specified, gets the color from the "_ColorRange" prop of the clip. This check is not performed if the input clip is float.

Methods:

Attributes:

Source code
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
def __init__(
    self, clip: vs.VideoNode, sigma: SingleOrArr[float] = 0.5, tr: SingleOrArr[int] | None = None,
    profile: Profile | Profile.Config = Profile.FAST, ref: vs.VideoNode | None = None, refine: int = 1,
    matrix: MatrixT | None = None, range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None, fp32: bool = True, *, radius: SingleOrArr[int] | MissingT = MISSING
) -> None:
    """
    :param clip:            Source clip.
    :param sigma:           Strength of denoising, valid range is [0, +inf].
    :param tr:              Temporal radius, valid range is [1, 16].
    :param profile:         Preset profile. See :py:attr:`vsdenoise.bm3d.Profile`.
                            Default: Profile.FAST.
    :param ref:             Reference clip used in block-matching, replacing the basic estimation.
                            If not specified, the input clip is used instead.
                            Default: None.
    :param refine:          The number of times to refine the estimation.
                             * 1 means basic estimate with one final estimate.
                             * n means basic estimate refined with final estimate applied n times.

                            Default: 1.
    :param matrix:          Enum for the matrix of the input clip.
                            See :py:attr:`vstools.enums.Matrix` for more info.
                            If not specified, gets the matrix from the "_Matrix" prop of the clip
                            unless it's an RGB clip, in which case it stays as `None`.
    :param range_in:        Enum for the color range of the input clip.
                            See :py:attr:`vstools.enums.ColorRange` for more info.
                            If not specified, gets the color from the "_ColorRange" prop of the clip.
                            This check is not performed if the input clip is float.
    """

    assert check_variable(clip, self.__class__)
    assert check_progressive(clip, self.__class__)

    self.sigma = self._Sigma(*normalize_seq(sigma, 3))
    self.tr = self._TemporalRadius(*normalize_seq(tr or 0, 2))

    _is_gray = clip.format.color_family == vs.GRAY

    if _is_gray:
        self.sigma = self.sigma._replace(u=0, v=0)
    elif sum(self.sigma[1:]) == 0:
        _is_gray = True

    if _is_gray:
        colorspace = Colorspace.GRAY
    elif colorspace is None:
        colorspace = Colorspace.OPP_BM3D

    matrix = Matrix.from_param(matrix)

    self.cspconfig = BM3DColorspaceConfig(colorspace, clip, matrix, self.sigma.y == 0, fp32)

    self.cspconfig.clip = self.cspconfig.check_clip(clip, matrix, range_in, self.__class__)

    self.profile = profile if isinstance(profile, ProfileBase.Config) else profile()
    self.ref = self.cspconfig.check_clip(ref, matrix, range_in, self.__class__)
    if refine < 1:
        raise CustomIndexError('"refine" must be >= 1!', self.__class__)

    self.refine = refine

    self.basic_args = {}
    self.final_args = {}

    self.__post_init__()

basic_args instance-attribute

basic_args: KwargsT = {}

Custom kwargs passed to bm3d for the :py:attr:basic clip.

cspconfig instance-attribute

cspconfig: BM3DColorspaceConfig = BM3DColorspaceConfig(
    colorspace, clip, matrix, y == 0, fp32
)

final_args instance-attribute

final_args: KwargsT = {}

Custom kwargs passed to bm3d for the :py:attr:final clip.

plugin instance-attribute

plugin: (
    _Plugin_bm3dcuda_Core_Bound
    | _Plugin_bm3dcuda_rtc_Core_Bound
    | _Plugin_bm3dcpu_Core_Bound
)

profile instance-attribute

profile: Config = profile if isinstance(profile, Config) else profile()

ref instance-attribute

ref: VideoNode | None = check_clip(ref, matrix, range_in, __class__)

refine instance-attribute

refine: int = refine

sigma instance-attribute

sigma: _Sigma = _Sigma(*normalize_seq(sigma, 3))

tr instance-attribute

tr: _TemporalRadius = _TemporalRadius(*normalize_seq(tr or 0, 2))

wclip instance-attribute

wclip: VideoNode

basic

basic(clip: VideoNode | None = None, opp: bool = False) -> VideoNode
Source code
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
def basic(self, clip: vs.VideoNode | None = None, opp: bool = False) -> vs.VideoNode:
    clip = self.cspconfig.get_clip(self.cspconfig.clip, self._pre_clip, clip)

    kwargs = self.profile.as_dict(
        self.plugin, True, False, self.basic_args, sigma=self.sigma, radius=self.tr.basic
    )

    if hasattr(self.plugin, 'BM3Dv2'):
        clip = self.plugin.BM3Dv2(clip, **kwargs)
    else:
        clip = self.plugin.BM3D(clip, **kwargs)

        if self.tr.basic:
            clip = clip.bm3d.VAggregate(self.tr.basic, self.cspconfig.fp32)

    return clip if opp else self.cspconfig.post_processing(clip)

denoise classmethod

denoise(
    clip: VideoNode,
    sigma: SingleOrArr[float] = 0.5,
    tr: SingleOrArr[int] | None = None,
    refine: int = 1,
    profile: Profile | Config = FAST,
    ref: VideoNode | None = None,
    matrix: MatrixT | None = None,
    range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None,
    fp32: bool = True,
    planes: PlanesT = None,
    **kwargs: Any
) -> VideoNode
Source code
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
@classmethod
def denoise(
    cls, clip: vs.VideoNode, sigma: SingleOrArr[float] = 0.5, tr: SingleOrArr[int] | None = None,
    refine: int = 1, profile: Profile | Profile.Config = Profile.FAST, ref: vs.VideoNode | None = None,
    matrix: MatrixT | None = None, range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None, fp32: bool = True, planes: PlanesT = None, **kwargs: Any
) -> vs.VideoNode:
    func = FunctionUtil(clip, cls.denoise, planes)

    sigma = func.norm_seq(sigma, 0)

    ref = get_y(ref) if func.luma_only and ref else ref

    bm3d = cls(func.work_clip, sigma, tr, profile, ref, refine, matrix, range_in, colorspace, fp32, **kwargs)

    if refine:
        denoise = bm3d.final()
    else:
        denoise = bm3d.basic(
            bm3d.cspconfig.get_clip(bm3d.cspconfig.clip, bm3d._pre_clip, None)
        )

    return func.return_clip(denoise)

final

final(
    clip: VideoNode | None = None,
    ref: VideoNode | None = None,
    refine: int | None = None,
) -> VideoNode
Source code
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
def final(
    self, clip: vs.VideoNode | None = None, ref: vs.VideoNode | None = None, refine: int | None = None
) -> vs.VideoNode:
    clip = self.cspconfig.get_clip(self.cspconfig.clip, self._pre_clip, clip)

    if self.ref and self._pre_ref:
        ref = self.cspconfig.get_clip(self.ref, self._pre_ref, ref)
    else:
        ref = self.basic(clip, True)

    kwargs = self.profile.as_dict(
        self.plugin, False, True, self.final_args, sigma=self.sigma, radius=self.tr.final
    )

    if hasattr(self.plugin, 'BM3Dv2'):
        for _ in range(refine or self.refine):
            clip = self.plugin.BM3Dv2(clip, ref, **kwargs)
    else:
        for _ in range(refine or self.refine):
            clip = self.plugin.BM3D(clip, ref, **kwargs)

            if self.tr.final:
                clip = clip.bm3d.VAggregate(self.tr.final, self.cspconfig.fp32)

    return self.cspconfig.post_processing(clip)

AbstractBM3DCudaMeta

Bases: ABCMeta

BM3D

BM3D(
    clip: VideoNode,
    sigma: SingleOrArr[float] = 0.5,
    tr: SingleOrArr[int] | None = None,
    profile: Profile | Config = FAST,
    ref: VideoNode | None = None,
    refine: int = 1,
    matrix: MatrixT | None = None,
    range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None,
    fp32: bool = True,
    *,
    radius: SingleOrArr[int] | MissingT = MISSING
)

Bases: AbstractBM3D

Parameters:

  • clip

    (VideoNode) –

    Source clip.

  • sigma

    (SingleOrArr[float], default: 0.5 ) –

    Strength of denoising, valid range is [0, +inf].

  • tr

    (SingleOrArr[int] | None, default: None ) –

    Temporal radius, valid range is [1, 16].

  • profile

    (Profile | Config, default: FAST ) –

    Preset profile. See :py:attr:vsdenoise.bm3d.Profile. Default: Profile.FAST.

  • ref

    (VideoNode | None, default: None ) –

    Reference clip used in block-matching, replacing the basic estimation. If not specified, the input clip is used instead. Default: None.

  • refine

    (int, default: 1 ) –

    The number of times to refine the estimation. * 1 means basic estimate with one final estimate. * n means basic estimate refined with final estimate applied n times. Default: 1.

  • matrix

    (MatrixT | None, default: None ) –

    Enum for the matrix of the input clip. See :py:attr:vstools.enums.Matrix for more info. If not specified, gets the matrix from the "_Matrix" prop of the clip unless it's an RGB clip, in which case it stays as None.

  • range_in

    (ColorRangeT | None, default: None ) –

    Enum for the color range of the input clip. See :py:attr:vstools.enums.ColorRange for more info. If not specified, gets the color from the "_ColorRange" prop of the clip. This check is not performed if the input clip is float.

Methods:

  • basic

    Retrieve the "basic" clip, typically used as a ref clip for :py:attr:final.

  • denoise
  • final

    Retrieve the "final" clip.

Attributes:

Source code
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
def __init__(
    self, clip: vs.VideoNode, sigma: SingleOrArr[float] = 0.5, tr: SingleOrArr[int] | None = None,
    profile: Profile | Profile.Config = Profile.FAST, ref: vs.VideoNode | None = None, refine: int = 1,
    matrix: MatrixT | None = None, range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None, fp32: bool = True, *, radius: SingleOrArr[int] | MissingT = MISSING
) -> None:
    """
    :param clip:            Source clip.
    :param sigma:           Strength of denoising, valid range is [0, +inf].
    :param tr:              Temporal radius, valid range is [1, 16].
    :param profile:         Preset profile. See :py:attr:`vsdenoise.bm3d.Profile`.
                            Default: Profile.FAST.
    :param ref:             Reference clip used in block-matching, replacing the basic estimation.
                            If not specified, the input clip is used instead.
                            Default: None.
    :param refine:          The number of times to refine the estimation.
                             * 1 means basic estimate with one final estimate.
                             * n means basic estimate refined with final estimate applied n times.

                            Default: 1.
    :param matrix:          Enum for the matrix of the input clip.
                            See :py:attr:`vstools.enums.Matrix` for more info.
                            If not specified, gets the matrix from the "_Matrix" prop of the clip
                            unless it's an RGB clip, in which case it stays as `None`.
    :param range_in:        Enum for the color range of the input clip.
                            See :py:attr:`vstools.enums.ColorRange` for more info.
                            If not specified, gets the color from the "_ColorRange" prop of the clip.
                            This check is not performed if the input clip is float.
    """

    assert check_variable(clip, self.__class__)
    assert check_progressive(clip, self.__class__)

    self.sigma = self._Sigma(*normalize_seq(sigma, 3))
    self.tr = self._TemporalRadius(*normalize_seq(tr or 0, 2))

    _is_gray = clip.format.color_family == vs.GRAY

    if _is_gray:
        self.sigma = self.sigma._replace(u=0, v=0)
    elif sum(self.sigma[1:]) == 0:
        _is_gray = True

    if _is_gray:
        colorspace = Colorspace.GRAY
    elif colorspace is None:
        colorspace = Colorspace.OPP_BM3D

    matrix = Matrix.from_param(matrix)

    self.cspconfig = BM3DColorspaceConfig(colorspace, clip, matrix, self.sigma.y == 0, fp32)

    self.cspconfig.clip = self.cspconfig.check_clip(clip, matrix, range_in, self.__class__)

    self.profile = profile if isinstance(profile, ProfileBase.Config) else profile()
    self.ref = self.cspconfig.check_clip(ref, matrix, range_in, self.__class__)
    if refine < 1:
        raise CustomIndexError('"refine" must be >= 1!', self.__class__)

    self.refine = refine

    self.basic_args = {}
    self.final_args = {}

    self.__post_init__()

basic_args instance-attribute

basic_args: KwargsT = {}

Custom kwargs passed to bm3d for the :py:attr:basic clip.

cspconfig instance-attribute

cspconfig: BM3DColorspaceConfig = BM3DColorspaceConfig(
    colorspace, clip, matrix, y == 0, fp32
)

final_args instance-attribute

final_args: KwargsT = {}

Custom kwargs passed to bm3d for the :py:attr:final clip.

profile instance-attribute

profile: Config = profile if isinstance(profile, Config) else profile()

ref instance-attribute

ref: VideoNode | None = check_clip(ref, matrix, range_in, __class__)

refine instance-attribute

refine: int = refine

sigma instance-attribute

sigma: _Sigma = _Sigma(*normalize_seq(sigma, 3))

tr instance-attribute

tr: _TemporalRadius = _TemporalRadius(*normalize_seq(tr or 0, 2))

wclip instance-attribute

wclip: VideoNode

basic abstractmethod

basic(clip: VideoNode, opp: bool = False) -> VideoNode

Retrieve the "basic" clip, typically used as a ref clip for :py:attr:final.

Parameters:

  • clip

    (VideoNode) –

    OPP or GRAY colorspace clip to be processed.

Returns:

  • VideoNode

    Denoised clip to be used as ref.

Source code
376
377
378
379
380
381
382
383
384
@abstractmethod
def basic(self, clip: vs.VideoNode, opp: bool = False) -> vs.VideoNode:
    """
    Retrieve the "basic" clip, typically used as a `ref` clip for :py:attr:`final`.

    :param clip:    OPP or GRAY colorspace clip to be processed.

    :return:        Denoised clip to be used as `ref`.
    """

denoise classmethod

denoise(
    clip: VideoNode,
    sigma: SingleOrArr[float] = 0.5,
    tr: SingleOrArr[int] | None = None,
    refine: int = 1,
    profile: Profile | Config = FAST,
    ref: VideoNode | None = None,
    matrix: MatrixT | None = None,
    range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None,
    fp32: bool = True,
    planes: PlanesT = None,
    **kwargs: Any
) -> VideoNode
Source code
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
@classmethod
def denoise(
    cls, clip: vs.VideoNode, sigma: SingleOrArr[float] = 0.5, tr: SingleOrArr[int] | None = None,
    refine: int = 1, profile: Profile | Profile.Config = Profile.FAST, ref: vs.VideoNode | None = None,
    matrix: MatrixT | None = None, range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None, fp32: bool = True, planes: PlanesT = None, **kwargs: Any
) -> vs.VideoNode:
    func = FunctionUtil(clip, cls.denoise, planes)

    sigma = func.norm_seq(sigma, 0)

    ref = get_y(ref) if func.luma_only and ref else ref

    bm3d = cls(func.work_clip, sigma, tr, profile, ref, refine, matrix, range_in, colorspace, fp32, **kwargs)

    if refine:
        denoise = bm3d.final()
    else:
        denoise = bm3d.basic(
            bm3d.cspconfig.get_clip(bm3d.cspconfig.clip, bm3d._pre_clip, None)
        )

    return func.return_clip(denoise)

final abstractmethod

final(
    clip: VideoNode | None = None,
    ref: VideoNode | None = None,
    refine: int | None = None,
) -> VideoNode

Retrieve the "final" clip.

Parameters:

  • clip

    (VideoNode | None, default: None ) –

    OPP or GRAY colorspace clip to be processed.

  • ref

    (VideoNode | None, default: None ) –

    Reference clip used for weight calculations.

Returns:

  • VideoNode

    Final, refined, denoised clip.

Source code
386
387
388
389
390
391
392
393
394
395
396
397
@abstractmethod
def final(
    self, clip: vs.VideoNode | None = None, ref: vs.VideoNode | None = None, refine: int | None = None
) -> vs.VideoNode:
    """
    Retrieve the "final" clip.

    :param clip:    OPP or GRAY colorspace clip to be processed.
    :param ref:     Reference clip used for weight calculations.

    :return:        Final, refined, denoised clip.
    """

BM3DCPU

BM3DCPU(
    clip: VideoNode,
    sigma: SingleOrArr[float] = 0.5,
    tr: SingleOrArr[int] | None = None,
    profile: Profile | Config = FAST,
    ref: VideoNode | None = None,
    refine: int = 1,
    matrix: MatrixT | None = None,
    range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None,
    fp32: bool = True,
    *,
    radius: SingleOrArr[int] | MissingT = MISSING
)

Bases: AbstractBM3DCuda

Parameters:

  • clip

    (VideoNode) –

    Source clip.

  • sigma

    (SingleOrArr[float], default: 0.5 ) –

    Strength of denoising, valid range is [0, +inf].

  • tr

    (SingleOrArr[int] | None, default: None ) –

    Temporal radius, valid range is [1, 16].

  • profile

    (Profile | Config, default: FAST ) –

    Preset profile. See :py:attr:vsdenoise.bm3d.Profile. Default: Profile.FAST.

  • ref

    (VideoNode | None, default: None ) –

    Reference clip used in block-matching, replacing the basic estimation. If not specified, the input clip is used instead. Default: None.

  • refine

    (int, default: 1 ) –

    The number of times to refine the estimation. * 1 means basic estimate with one final estimate. * n means basic estimate refined with final estimate applied n times. Default: 1.

  • matrix

    (MatrixT | None, default: None ) –

    Enum for the matrix of the input clip. See :py:attr:vstools.enums.Matrix for more info. If not specified, gets the matrix from the "_Matrix" prop of the clip unless it's an RGB clip, in which case it stays as None.

  • range_in

    (ColorRangeT | None, default: None ) –

    Enum for the color range of the input clip. See :py:attr:vstools.enums.ColorRange for more info. If not specified, gets the color from the "_ColorRange" prop of the clip. This check is not performed if the input clip is float.

Methods:

Attributes:

Source code
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
def __init__(
    self, clip: vs.VideoNode, sigma: SingleOrArr[float] = 0.5, tr: SingleOrArr[int] | None = None,
    profile: Profile | Profile.Config = Profile.FAST, ref: vs.VideoNode | None = None, refine: int = 1,
    matrix: MatrixT | None = None, range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None, fp32: bool = True, *, radius: SingleOrArr[int] | MissingT = MISSING
) -> None:
    """
    :param clip:            Source clip.
    :param sigma:           Strength of denoising, valid range is [0, +inf].
    :param tr:              Temporal radius, valid range is [1, 16].
    :param profile:         Preset profile. See :py:attr:`vsdenoise.bm3d.Profile`.
                            Default: Profile.FAST.
    :param ref:             Reference clip used in block-matching, replacing the basic estimation.
                            If not specified, the input clip is used instead.
                            Default: None.
    :param refine:          The number of times to refine the estimation.
                             * 1 means basic estimate with one final estimate.
                             * n means basic estimate refined with final estimate applied n times.

                            Default: 1.
    :param matrix:          Enum for the matrix of the input clip.
                            See :py:attr:`vstools.enums.Matrix` for more info.
                            If not specified, gets the matrix from the "_Matrix" prop of the clip
                            unless it's an RGB clip, in which case it stays as `None`.
    :param range_in:        Enum for the color range of the input clip.
                            See :py:attr:`vstools.enums.ColorRange` for more info.
                            If not specified, gets the color from the "_ColorRange" prop of the clip.
                            This check is not performed if the input clip is float.
    """

    assert check_variable(clip, self.__class__)
    assert check_progressive(clip, self.__class__)

    self.sigma = self._Sigma(*normalize_seq(sigma, 3))
    self.tr = self._TemporalRadius(*normalize_seq(tr or 0, 2))

    _is_gray = clip.format.color_family == vs.GRAY

    if _is_gray:
        self.sigma = self.sigma._replace(u=0, v=0)
    elif sum(self.sigma[1:]) == 0:
        _is_gray = True

    if _is_gray:
        colorspace = Colorspace.GRAY
    elif colorspace is None:
        colorspace = Colorspace.OPP_BM3D

    matrix = Matrix.from_param(matrix)

    self.cspconfig = BM3DColorspaceConfig(colorspace, clip, matrix, self.sigma.y == 0, fp32)

    self.cspconfig.clip = self.cspconfig.check_clip(clip, matrix, range_in, self.__class__)

    self.profile = profile if isinstance(profile, ProfileBase.Config) else profile()
    self.ref = self.cspconfig.check_clip(ref, matrix, range_in, self.__class__)
    if refine < 1:
        raise CustomIndexError('"refine" must be >= 1!', self.__class__)

    self.refine = refine

    self.basic_args = {}
    self.final_args = {}

    self.__post_init__()

basic_args instance-attribute

basic_args: KwargsT = {}

Custom kwargs passed to bm3d for the :py:attr:basic clip.

cspconfig instance-attribute

cspconfig: BM3DColorspaceConfig = BM3DColorspaceConfig(
    colorspace, clip, matrix, y == 0, fp32
)

final_args instance-attribute

final_args: KwargsT = {}

Custom kwargs passed to bm3d for the :py:attr:final clip.

plugin instance-attribute

plugin: (
    _Plugin_bm3dcuda_Core_Bound
    | _Plugin_bm3dcuda_rtc_Core_Bound
    | _Plugin_bm3dcpu_Core_Bound
)

profile instance-attribute

profile: Config = profile if isinstance(profile, Config) else profile()

ref instance-attribute

ref: VideoNode | None = check_clip(ref, matrix, range_in, __class__)

refine instance-attribute

refine: int = refine

sigma instance-attribute

sigma: _Sigma = _Sigma(*normalize_seq(sigma, 3))

tr instance-attribute

tr: _TemporalRadius = _TemporalRadius(*normalize_seq(tr or 0, 2))

wclip instance-attribute

wclip: VideoNode

basic

basic(clip: VideoNode | None = None, opp: bool = False) -> VideoNode
Source code
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
def basic(self, clip: vs.VideoNode | None = None, opp: bool = False) -> vs.VideoNode:
    clip = self.cspconfig.get_clip(self.cspconfig.clip, self._pre_clip, clip)

    kwargs = self.profile.as_dict(
        self.plugin, True, False, self.basic_args, sigma=self.sigma, radius=self.tr.basic
    )

    if hasattr(self.plugin, 'BM3Dv2'):
        clip = self.plugin.BM3Dv2(clip, **kwargs)
    else:
        clip = self.plugin.BM3D(clip, **kwargs)

        if self.tr.basic:
            clip = clip.bm3d.VAggregate(self.tr.basic, self.cspconfig.fp32)

    return clip if opp else self.cspconfig.post_processing(clip)

denoise classmethod

denoise(
    clip: VideoNode,
    sigma: SingleOrArr[float] = 0.5,
    tr: SingleOrArr[int] | None = None,
    refine: int = 1,
    profile: Profile | Config = FAST,
    ref: VideoNode | None = None,
    matrix: MatrixT | None = None,
    range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None,
    fp32: bool = True,
    planes: PlanesT = None,
    **kwargs: Any
) -> VideoNode
Source code
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
@classmethod
def denoise(
    cls, clip: vs.VideoNode, sigma: SingleOrArr[float] = 0.5, tr: SingleOrArr[int] | None = None,
    refine: int = 1, profile: Profile | Profile.Config = Profile.FAST, ref: vs.VideoNode | None = None,
    matrix: MatrixT | None = None, range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None, fp32: bool = True, planes: PlanesT = None, **kwargs: Any
) -> vs.VideoNode:
    func = FunctionUtil(clip, cls.denoise, planes)

    sigma = func.norm_seq(sigma, 0)

    ref = get_y(ref) if func.luma_only and ref else ref

    bm3d = cls(func.work_clip, sigma, tr, profile, ref, refine, matrix, range_in, colorspace, fp32, **kwargs)

    if refine:
        denoise = bm3d.final()
    else:
        denoise = bm3d.basic(
            bm3d.cspconfig.get_clip(bm3d.cspconfig.clip, bm3d._pre_clip, None)
        )

    return func.return_clip(denoise)

final

final(
    clip: VideoNode | None = None,
    ref: VideoNode | None = None,
    refine: int | None = None,
) -> VideoNode
Source code
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
def final(
    self, clip: vs.VideoNode | None = None, ref: vs.VideoNode | None = None, refine: int | None = None
) -> vs.VideoNode:
    clip = self.cspconfig.get_clip(self.cspconfig.clip, self._pre_clip, clip)

    if self.ref and self._pre_ref:
        ref = self.cspconfig.get_clip(self.ref, self._pre_ref, ref)
    else:
        ref = self.basic(clip, True)

    kwargs = self.profile.as_dict(
        self.plugin, False, True, self.final_args, sigma=self.sigma, radius=self.tr.final
    )

    if hasattr(self.plugin, 'BM3Dv2'):
        for _ in range(refine or self.refine):
            clip = self.plugin.BM3Dv2(clip, ref, **kwargs)
    else:
        for _ in range(refine or self.refine):
            clip = self.plugin.BM3D(clip, ref, **kwargs)

            if self.tr.final:
                clip = clip.bm3d.VAggregate(self.tr.final, self.cspconfig.fp32)

    return self.cspconfig.post_processing(clip)

BM3DColorspaceConfig dataclass

BM3DColorspaceConfig(
    csp: Colorspace,
    clip: ConstantFormatVideoNode,
    matrix: Matrix | None,
    chroma_only: bool,
    fp32: bool,
)

Methods:

Attributes:

chroma_only instance-attribute

chroma_only: bool

clip instance-attribute

clip: ConstantFormatVideoNode

csp instance-attribute

fp32 instance-attribute

fp32: bool

matrix instance-attribute

matrix: Matrix | None

check_clip

check_clip(
    clip: VideoNode,
    matrix: MatrixT | None,
    range_in: ColorRangeT | None,
    func: FuncExceptT,
) -> ConstantFormatVideoNode
check_clip(
    clip: None,
    matrix: MatrixT | None,
    range_in: ColorRangeT | None,
    func: FuncExceptT,
) -> None
check_clip(
    clip: VideoNode | None,
    matrix: MatrixT | None,
    range_in: ColorRangeT | None,
    func: FuncExceptT,
) -> ConstantFormatVideoNode | None
Source code
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
def check_clip(
    self, clip: vs.VideoNode | None, matrix: MatrixT | None, range_in: ColorRangeT | None, func: FuncExceptT
) -> ConstantFormatVideoNode | None:
    if clip is None:
        return None

    fmt = get_video_format(clip)

    if fmt.sample_type != vs.FLOAT or fmt.bits_per_sample != 32:
        clip = ColorRange.ensure_presence(clip, range_in or ColorRange.from_video(clip), func)

    if fmt.color_family == vs.YUV and (self.csp.is_rgb or self.csp.is_opp):
        clip = Matrix.ensure_presence(clip, matrix, func)

    assert check_variable(clip, func)

    return clip

get_clip

get_clip(
    base: VideoNode, pre: VideoNode, ref: VideoNode | None = None
) -> VideoNode
Source code
71
72
def get_clip(self, base: vs.VideoNode, pre: vs.VideoNode, ref: vs.VideoNode | None = None) -> vs.VideoNode:
    return pre if ref is None or ref is base or ref is pre else self.prepare_clip(ref)

post_processing

post_processing(clip: VideoNode) -> VideoNode
Source code
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
def post_processing(self, clip: vs.VideoNode) -> vs.VideoNode:
    assert clip.format

    if self.clip.format.color_family is vs.YUV:
        if clip.format.color_family is vs.GRAY:
            clip = join(depth(clip, self.clip), self.clip)
        else:
            clip = self.csp.to_yuv(clip, self.fp32, self.post_processing, self.clip, matrix=self.matrix)
    elif self.clip.format.color_family is vs.RGB:
        clip = self.csp.to_rgb(clip, self.fp32, self.post_processing, self.clip)

    if self.chroma_only:
        clip = join(self.clip, clip)

    return depth(clip, self.clip)

prepare_clip

prepare_clip(clip: VideoNode) -> VideoNode
prepare_clip(clip: None) -> None
prepare_clip(clip: VideoNode | None) -> VideoNode | None
Source code
82
83
84
85
86
87
88
def prepare_clip(self, clip: vs.VideoNode | None) -> vs.VideoNode | None:
    if clip is None:
        return None

    assert check_variable(clip, self.prepare_clip)

    return self.csp.from_clip(clip, self.fp32, self.prepare_clip)

BM3DCuda

BM3DCuda(
    clip: VideoNode,
    sigma: SingleOrArr[float] = 0.5,
    tr: SingleOrArr[int] | None = None,
    profile: Profile | Config = FAST,
    ref: VideoNode | None = None,
    refine: int = 1,
    matrix: MatrixT | None = None,
    range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None,
    fp32: bool = True,
    *,
    radius: SingleOrArr[int] | MissingT = MISSING
)

Bases: AbstractBM3DCuda

Parameters:

  • clip

    (VideoNode) –

    Source clip.

  • sigma

    (SingleOrArr[float], default: 0.5 ) –

    Strength of denoising, valid range is [0, +inf].

  • tr

    (SingleOrArr[int] | None, default: None ) –

    Temporal radius, valid range is [1, 16].

  • profile

    (Profile | Config, default: FAST ) –

    Preset profile. See :py:attr:vsdenoise.bm3d.Profile. Default: Profile.FAST.

  • ref

    (VideoNode | None, default: None ) –

    Reference clip used in block-matching, replacing the basic estimation. If not specified, the input clip is used instead. Default: None.

  • refine

    (int, default: 1 ) –

    The number of times to refine the estimation. * 1 means basic estimate with one final estimate. * n means basic estimate refined with final estimate applied n times. Default: 1.

  • matrix

    (MatrixT | None, default: None ) –

    Enum for the matrix of the input clip. See :py:attr:vstools.enums.Matrix for more info. If not specified, gets the matrix from the "_Matrix" prop of the clip unless it's an RGB clip, in which case it stays as None.

  • range_in

    (ColorRangeT | None, default: None ) –

    Enum for the color range of the input clip. See :py:attr:vstools.enums.ColorRange for more info. If not specified, gets the color from the "_ColorRange" prop of the clip. This check is not performed if the input clip is float.

Methods:

Attributes:

Source code
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
def __init__(
    self, clip: vs.VideoNode, sigma: SingleOrArr[float] = 0.5, tr: SingleOrArr[int] | None = None,
    profile: Profile | Profile.Config = Profile.FAST, ref: vs.VideoNode | None = None, refine: int = 1,
    matrix: MatrixT | None = None, range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None, fp32: bool = True, *, radius: SingleOrArr[int] | MissingT = MISSING
) -> None:
    """
    :param clip:            Source clip.
    :param sigma:           Strength of denoising, valid range is [0, +inf].
    :param tr:              Temporal radius, valid range is [1, 16].
    :param profile:         Preset profile. See :py:attr:`vsdenoise.bm3d.Profile`.
                            Default: Profile.FAST.
    :param ref:             Reference clip used in block-matching, replacing the basic estimation.
                            If not specified, the input clip is used instead.
                            Default: None.
    :param refine:          The number of times to refine the estimation.
                             * 1 means basic estimate with one final estimate.
                             * n means basic estimate refined with final estimate applied n times.

                            Default: 1.
    :param matrix:          Enum for the matrix of the input clip.
                            See :py:attr:`vstools.enums.Matrix` for more info.
                            If not specified, gets the matrix from the "_Matrix" prop of the clip
                            unless it's an RGB clip, in which case it stays as `None`.
    :param range_in:        Enum for the color range of the input clip.
                            See :py:attr:`vstools.enums.ColorRange` for more info.
                            If not specified, gets the color from the "_ColorRange" prop of the clip.
                            This check is not performed if the input clip is float.
    """

    assert check_variable(clip, self.__class__)
    assert check_progressive(clip, self.__class__)

    self.sigma = self._Sigma(*normalize_seq(sigma, 3))
    self.tr = self._TemporalRadius(*normalize_seq(tr or 0, 2))

    _is_gray = clip.format.color_family == vs.GRAY

    if _is_gray:
        self.sigma = self.sigma._replace(u=0, v=0)
    elif sum(self.sigma[1:]) == 0:
        _is_gray = True

    if _is_gray:
        colorspace = Colorspace.GRAY
    elif colorspace is None:
        colorspace = Colorspace.OPP_BM3D

    matrix = Matrix.from_param(matrix)

    self.cspconfig = BM3DColorspaceConfig(colorspace, clip, matrix, self.sigma.y == 0, fp32)

    self.cspconfig.clip = self.cspconfig.check_clip(clip, matrix, range_in, self.__class__)

    self.profile = profile if isinstance(profile, ProfileBase.Config) else profile()
    self.ref = self.cspconfig.check_clip(ref, matrix, range_in, self.__class__)
    if refine < 1:
        raise CustomIndexError('"refine" must be >= 1!', self.__class__)

    self.refine = refine

    self.basic_args = {}
    self.final_args = {}

    self.__post_init__()

basic_args instance-attribute

basic_args: KwargsT = {}

Custom kwargs passed to bm3d for the :py:attr:basic clip.

cspconfig instance-attribute

cspconfig: BM3DColorspaceConfig = BM3DColorspaceConfig(
    colorspace, clip, matrix, y == 0, fp32
)

final_args instance-attribute

final_args: KwargsT = {}

Custom kwargs passed to bm3d for the :py:attr:final clip.

plugin instance-attribute

plugin: (
    _Plugin_bm3dcuda_Core_Bound
    | _Plugin_bm3dcuda_rtc_Core_Bound
    | _Plugin_bm3dcpu_Core_Bound
)

profile instance-attribute

profile: Config = profile if isinstance(profile, Config) else profile()

ref instance-attribute

ref: VideoNode | None = check_clip(ref, matrix, range_in, __class__)

refine instance-attribute

refine: int = refine

sigma instance-attribute

sigma: _Sigma = _Sigma(*normalize_seq(sigma, 3))

tr instance-attribute

tr: _TemporalRadius = _TemporalRadius(*normalize_seq(tr or 0, 2))

wclip instance-attribute

wclip: VideoNode

basic

basic(clip: VideoNode | None = None, opp: bool = False) -> VideoNode
Source code
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
def basic(self, clip: vs.VideoNode | None = None, opp: bool = False) -> vs.VideoNode:
    clip = self.cspconfig.get_clip(self.cspconfig.clip, self._pre_clip, clip)

    kwargs = self.profile.as_dict(
        self.plugin, True, False, self.basic_args, sigma=self.sigma, radius=self.tr.basic
    )

    if hasattr(self.plugin, 'BM3Dv2'):
        clip = self.plugin.BM3Dv2(clip, **kwargs)
    else:
        clip = self.plugin.BM3D(clip, **kwargs)

        if self.tr.basic:
            clip = clip.bm3d.VAggregate(self.tr.basic, self.cspconfig.fp32)

    return clip if opp else self.cspconfig.post_processing(clip)

denoise classmethod

denoise(
    clip: VideoNode,
    sigma: SingleOrArr[float] = 0.5,
    tr: SingleOrArr[int] | None = None,
    refine: int = 1,
    profile: Profile | Config = FAST,
    ref: VideoNode | None = None,
    matrix: MatrixT | None = None,
    range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None,
    fp32: bool = True,
    planes: PlanesT = None,
    **kwargs: Any
) -> VideoNode
Source code
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
@classmethod
def denoise(
    cls, clip: vs.VideoNode, sigma: SingleOrArr[float] = 0.5, tr: SingleOrArr[int] | None = None,
    refine: int = 1, profile: Profile | Profile.Config = Profile.FAST, ref: vs.VideoNode | None = None,
    matrix: MatrixT | None = None, range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None, fp32: bool = True, planes: PlanesT = None, **kwargs: Any
) -> vs.VideoNode:
    func = FunctionUtil(clip, cls.denoise, planes)

    sigma = func.norm_seq(sigma, 0)

    ref = get_y(ref) if func.luma_only and ref else ref

    bm3d = cls(func.work_clip, sigma, tr, profile, ref, refine, matrix, range_in, colorspace, fp32, **kwargs)

    if refine:
        denoise = bm3d.final()
    else:
        denoise = bm3d.basic(
            bm3d.cspconfig.get_clip(bm3d.cspconfig.clip, bm3d._pre_clip, None)
        )

    return func.return_clip(denoise)

final

final(
    clip: VideoNode | None = None,
    ref: VideoNode | None = None,
    refine: int | None = None,
) -> VideoNode
Source code
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
def final(
    self, clip: vs.VideoNode | None = None, ref: vs.VideoNode | None = None, refine: int | None = None
) -> vs.VideoNode:
    clip = self.cspconfig.get_clip(self.cspconfig.clip, self._pre_clip, clip)

    if self.ref and self._pre_ref:
        ref = self.cspconfig.get_clip(self.ref, self._pre_ref, ref)
    else:
        ref = self.basic(clip, True)

    kwargs = self.profile.as_dict(
        self.plugin, False, True, self.final_args, sigma=self.sigma, radius=self.tr.final
    )

    if hasattr(self.plugin, 'BM3Dv2'):
        for _ in range(refine or self.refine):
            clip = self.plugin.BM3Dv2(clip, ref, **kwargs)
    else:
        for _ in range(refine or self.refine):
            clip = self.plugin.BM3D(clip, ref, **kwargs)

            if self.tr.final:
                clip = clip.bm3d.VAggregate(self.tr.final, self.cspconfig.fp32)

    return self.cspconfig.post_processing(clip)

BM3DCudaRTC

BM3DCudaRTC(
    clip: VideoNode,
    sigma: SingleOrArr[float] = 0.5,
    tr: SingleOrArr[int] | None = None,
    profile: Profile | Config = FAST,
    ref: VideoNode | None = None,
    refine: int = 1,
    matrix: MatrixT | None = None,
    range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None,
    fp32: bool = True,
    *,
    radius: SingleOrArr[int] | MissingT = MISSING
)

Bases: AbstractBM3DCuda

Parameters:

  • clip

    (VideoNode) –

    Source clip.

  • sigma

    (SingleOrArr[float], default: 0.5 ) –

    Strength of denoising, valid range is [0, +inf].

  • tr

    (SingleOrArr[int] | None, default: None ) –

    Temporal radius, valid range is [1, 16].

  • profile

    (Profile | Config, default: FAST ) –

    Preset profile. See :py:attr:vsdenoise.bm3d.Profile. Default: Profile.FAST.

  • ref

    (VideoNode | None, default: None ) –

    Reference clip used in block-matching, replacing the basic estimation. If not specified, the input clip is used instead. Default: None.

  • refine

    (int, default: 1 ) –

    The number of times to refine the estimation. * 1 means basic estimate with one final estimate. * n means basic estimate refined with final estimate applied n times. Default: 1.

  • matrix

    (MatrixT | None, default: None ) –

    Enum for the matrix of the input clip. See :py:attr:vstools.enums.Matrix for more info. If not specified, gets the matrix from the "_Matrix" prop of the clip unless it's an RGB clip, in which case it stays as None.

  • range_in

    (ColorRangeT | None, default: None ) –

    Enum for the color range of the input clip. See :py:attr:vstools.enums.ColorRange for more info. If not specified, gets the color from the "_ColorRange" prop of the clip. This check is not performed if the input clip is float.

Methods:

Attributes:

Source code
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
def __init__(
    self, clip: vs.VideoNode, sigma: SingleOrArr[float] = 0.5, tr: SingleOrArr[int] | None = None,
    profile: Profile | Profile.Config = Profile.FAST, ref: vs.VideoNode | None = None, refine: int = 1,
    matrix: MatrixT | None = None, range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None, fp32: bool = True, *, radius: SingleOrArr[int] | MissingT = MISSING
) -> None:
    """
    :param clip:            Source clip.
    :param sigma:           Strength of denoising, valid range is [0, +inf].
    :param tr:              Temporal radius, valid range is [1, 16].
    :param profile:         Preset profile. See :py:attr:`vsdenoise.bm3d.Profile`.
                            Default: Profile.FAST.
    :param ref:             Reference clip used in block-matching, replacing the basic estimation.
                            If not specified, the input clip is used instead.
                            Default: None.
    :param refine:          The number of times to refine the estimation.
                             * 1 means basic estimate with one final estimate.
                             * n means basic estimate refined with final estimate applied n times.

                            Default: 1.
    :param matrix:          Enum for the matrix of the input clip.
                            See :py:attr:`vstools.enums.Matrix` for more info.
                            If not specified, gets the matrix from the "_Matrix" prop of the clip
                            unless it's an RGB clip, in which case it stays as `None`.
    :param range_in:        Enum for the color range of the input clip.
                            See :py:attr:`vstools.enums.ColorRange` for more info.
                            If not specified, gets the color from the "_ColorRange" prop of the clip.
                            This check is not performed if the input clip is float.
    """

    assert check_variable(clip, self.__class__)
    assert check_progressive(clip, self.__class__)

    self.sigma = self._Sigma(*normalize_seq(sigma, 3))
    self.tr = self._TemporalRadius(*normalize_seq(tr or 0, 2))

    _is_gray = clip.format.color_family == vs.GRAY

    if _is_gray:
        self.sigma = self.sigma._replace(u=0, v=0)
    elif sum(self.sigma[1:]) == 0:
        _is_gray = True

    if _is_gray:
        colorspace = Colorspace.GRAY
    elif colorspace is None:
        colorspace = Colorspace.OPP_BM3D

    matrix = Matrix.from_param(matrix)

    self.cspconfig = BM3DColorspaceConfig(colorspace, clip, matrix, self.sigma.y == 0, fp32)

    self.cspconfig.clip = self.cspconfig.check_clip(clip, matrix, range_in, self.__class__)

    self.profile = profile if isinstance(profile, ProfileBase.Config) else profile()
    self.ref = self.cspconfig.check_clip(ref, matrix, range_in, self.__class__)
    if refine < 1:
        raise CustomIndexError('"refine" must be >= 1!', self.__class__)

    self.refine = refine

    self.basic_args = {}
    self.final_args = {}

    self.__post_init__()

basic_args instance-attribute

basic_args: KwargsT = {}

Custom kwargs passed to bm3d for the :py:attr:basic clip.

cspconfig instance-attribute

cspconfig: BM3DColorspaceConfig = BM3DColorspaceConfig(
    colorspace, clip, matrix, y == 0, fp32
)

final_args instance-attribute

final_args: KwargsT = {}

Custom kwargs passed to bm3d for the :py:attr:final clip.

plugin instance-attribute

plugin: (
    _Plugin_bm3dcuda_Core_Bound
    | _Plugin_bm3dcuda_rtc_Core_Bound
    | _Plugin_bm3dcpu_Core_Bound
)

profile instance-attribute

profile: Config = profile if isinstance(profile, Config) else profile()

ref instance-attribute

ref: VideoNode | None = check_clip(ref, matrix, range_in, __class__)

refine instance-attribute

refine: int = refine

sigma instance-attribute

sigma: _Sigma = _Sigma(*normalize_seq(sigma, 3))

tr instance-attribute

tr: _TemporalRadius = _TemporalRadius(*normalize_seq(tr or 0, 2))

wclip instance-attribute

wclip: VideoNode

basic

basic(clip: VideoNode | None = None, opp: bool = False) -> VideoNode
Source code
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
def basic(self, clip: vs.VideoNode | None = None, opp: bool = False) -> vs.VideoNode:
    clip = self.cspconfig.get_clip(self.cspconfig.clip, self._pre_clip, clip)

    kwargs = self.profile.as_dict(
        self.plugin, True, False, self.basic_args, sigma=self.sigma, radius=self.tr.basic
    )

    if hasattr(self.plugin, 'BM3Dv2'):
        clip = self.plugin.BM3Dv2(clip, **kwargs)
    else:
        clip = self.plugin.BM3D(clip, **kwargs)

        if self.tr.basic:
            clip = clip.bm3d.VAggregate(self.tr.basic, self.cspconfig.fp32)

    return clip if opp else self.cspconfig.post_processing(clip)

denoise classmethod

denoise(
    clip: VideoNode,
    sigma: SingleOrArr[float] = 0.5,
    tr: SingleOrArr[int] | None = None,
    refine: int = 1,
    profile: Profile | Config = FAST,
    ref: VideoNode | None = None,
    matrix: MatrixT | None = None,
    range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None,
    fp32: bool = True,
    planes: PlanesT = None,
    **kwargs: Any
) -> VideoNode
Source code
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
@classmethod
def denoise(
    cls, clip: vs.VideoNode, sigma: SingleOrArr[float] = 0.5, tr: SingleOrArr[int] | None = None,
    refine: int = 1, profile: Profile | Profile.Config = Profile.FAST, ref: vs.VideoNode | None = None,
    matrix: MatrixT | None = None, range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None, fp32: bool = True, planes: PlanesT = None, **kwargs: Any
) -> vs.VideoNode:
    func = FunctionUtil(clip, cls.denoise, planes)

    sigma = func.norm_seq(sigma, 0)

    ref = get_y(ref) if func.luma_only and ref else ref

    bm3d = cls(func.work_clip, sigma, tr, profile, ref, refine, matrix, range_in, colorspace, fp32, **kwargs)

    if refine:
        denoise = bm3d.final()
    else:
        denoise = bm3d.basic(
            bm3d.cspconfig.get_clip(bm3d.cspconfig.clip, bm3d._pre_clip, None)
        )

    return func.return_clip(denoise)

final

final(
    clip: VideoNode | None = None,
    ref: VideoNode | None = None,
    refine: int | None = None,
) -> VideoNode
Source code
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
def final(
    self, clip: vs.VideoNode | None = None, ref: vs.VideoNode | None = None, refine: int | None = None
) -> vs.VideoNode:
    clip = self.cspconfig.get_clip(self.cspconfig.clip, self._pre_clip, clip)

    if self.ref and self._pre_ref:
        ref = self.cspconfig.get_clip(self.ref, self._pre_ref, ref)
    else:
        ref = self.basic(clip, True)

    kwargs = self.profile.as_dict(
        self.plugin, False, True, self.final_args, sigma=self.sigma, radius=self.tr.final
    )

    if hasattr(self.plugin, 'BM3Dv2'):
        for _ in range(refine or self.refine):
            clip = self.plugin.BM3Dv2(clip, ref, **kwargs)
    else:
        for _ in range(refine or self.refine):
            clip = self.plugin.BM3D(clip, ref, **kwargs)

            if self.tr.final:
                clip = clip.bm3d.VAggregate(self.tr.final, self.cspconfig.fp32)

    return self.cspconfig.post_processing(clip)

BM3DMawen

BM3DMawen(
    clip: VideoNode,
    sigma: SingleOrArr[float] = 0.5,
    tr: SingleOrArr[int] | None = None,
    profile: Profile | Config = FAST,
    pre: VideoNode | None = None,
    ref: VideoNode | None = None,
    refine: int = 1,
    matrix: MatrixT | None = None,
    range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None,
    fp32: bool = True,
    *,
    radius: SingleOrArr[int] | MissingT = MISSING
)

Bases: AbstractBM3D

BM3D implementation by mawen1250.

Methods:

Attributes:

Source code
439
440
441
442
443
444
445
446
447
448
def __init__(
    self, clip: vs.VideoNode, sigma: SingleOrArr[float] = 0.5, tr: SingleOrArr[int] | None = None,
    profile: Profile | Profile.Config = Profile.FAST, pre: vs.VideoNode | None = None,
    ref: vs.VideoNode | None = None, refine: int = 1, matrix: MatrixT | None = None,
    range_in: ColorRangeT | None = None, colorspace: Colorspace | None = None, fp32: bool = True,
    *, radius: SingleOrArr[int] | MissingT = MISSING
) -> None:
    super().__init__(clip, sigma, tr, profile, ref, refine, matrix, range_in, colorspace, fp32, radius=radius)

    self.pre = pre and self.cspconfig.check_clip(pre, matrix, range_in, self.__class__)

basic_args instance-attribute

basic_args: KwargsT = {}

Custom kwargs passed to bm3d for the :py:attr:basic clip.

cspconfig instance-attribute

cspconfig: BM3DColorspaceConfig = BM3DColorspaceConfig(
    colorspace, clip, matrix, y == 0, fp32
)

final_args instance-attribute

final_args: KwargsT = {}

Custom kwargs passed to bm3d for the :py:attr:final clip.

pre instance-attribute

pre = pre and check_clip(pre, matrix, range_in, __class__)

profile instance-attribute

profile: Config = profile if isinstance(profile, Config) else profile()

ref instance-attribute

ref: VideoNode | None = check_clip(ref, matrix, range_in, __class__)

refine instance-attribute

refine: int = refine

sigma instance-attribute

sigma: _Sigma = _Sigma(*normalize_seq(sigma, 3))

tr instance-attribute

tr: _TemporalRadius = _TemporalRadius(*normalize_seq(tr or 0, 2))

wclip instance-attribute

wclip: VideoNode

basic

basic(clip: VideoNode | None = None, opp: bool = False) -> VideoNode
Source code
455
456
457
458
459
460
461
462
463
464
465
466
467
def basic(self, clip: vs.VideoNode | None = None, opp: bool = False) -> vs.VideoNode:
    clip = self.cspconfig.get_clip(self.cspconfig.clip, self._pre_clip, clip)

    kwargs = KwargsT(ref=self.pre, sigma=self.sigma, matrix=100, args=self.basic_args)

    if self.tr.basic:
        clip = clip.bm3d.VBasic(**self.profile.as_dict(**kwargs, radius=self.tr.basic))  # type: ignore

        clip = clip.bm3d.VAggregate(self.tr.basic, self.cspconfig.fp32)
    else:
        clip = clip.bm3d.Basic(**self.profile.as_dict(**kwargs))  # type: ignore

    return clip if opp else self.cspconfig.post_processing(clip)

denoise classmethod

denoise(
    clip: VideoNode,
    sigma: SingleOrArr[float] = 0.5,
    tr: SingleOrArr[int] | None = None,
    refine: int = 1,
    profile: Profile | Config = FAST,
    ref: VideoNode | None = None,
    matrix: MatrixT | None = None,
    range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None,
    fp32: bool = True,
    planes: PlanesT = None,
    **kwargs: Any
) -> VideoNode
Source code
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
@classmethod
def denoise(
    cls, clip: vs.VideoNode, sigma: SingleOrArr[float] = 0.5, tr: SingleOrArr[int] | None = None,
    refine: int = 1, profile: Profile | Profile.Config = Profile.FAST, ref: vs.VideoNode | None = None,
    matrix: MatrixT | None = None, range_in: ColorRangeT | None = None,
    colorspace: Colorspace | None = None, fp32: bool = True, planes: PlanesT = None, **kwargs: Any
) -> vs.VideoNode:
    func = FunctionUtil(clip, cls.denoise, planes)

    sigma = func.norm_seq(sigma, 0)

    ref = get_y(ref) if func.luma_only and ref else ref

    bm3d = cls(func.work_clip, sigma, tr, profile, ref, refine, matrix, range_in, colorspace, fp32, **kwargs)

    if refine:
        denoise = bm3d.final()
    else:
        denoise = bm3d.basic(
            bm3d.cspconfig.get_clip(bm3d.cspconfig.clip, bm3d._pre_clip, None)
        )

    return func.return_clip(denoise)

final

final(
    clip: VideoNode | None = None,
    ref: VideoNode | None = None,
    refine: int | None = None,
) -> VideoNode
Source code
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
def final(
    self, clip: vs.VideoNode | None = None, ref: vs.VideoNode | None = None, refine: int | None = None
) -> vs.VideoNode:
    clip = self.cspconfig.get_clip(self.cspconfig.clip, self._pre_clip, clip)

    if self.ref and self._pre_ref:
        ref = self.cspconfig.get_clip(self.ref, self._pre_ref, ref)
    else:
        ref = self.basic(clip, True)

    kwargs = KwargsT(ref=ref, sigma=self.sigma, matrix=100, args=self.final_args)

    for _ in range(refine or self.refine):
        if self.tr.final:
            clip = clip.bm3d.VFinal(**self.profile.as_dict(**kwargs, radius=self.tr.final))  # type: ignore
            clip = clip.bm3d.VAggregate(self.tr.final, self.cspconfig.fp32)
        else:
            clip = clip.bm3d.Final(**self.profile.as_dict(**kwargs))  # type: ignore

    return self.cspconfig.post_processing(clip)

Profile

Bases: ProfileBase, CustomStrEnum

BM3D profiles that set default parameters for each of them.

See the original documentation for more information:

https://github.com/HomeOfVapourSynthEvolution/VapourSynth-BM3D#profile-default

Classes:

  • Config

    Profile config for arguments passed to the bm3d implementation basic/final calls.

Methods:

Attributes:

  • CUSTOM

    Member for your own profile with no defaults.

  • FAST

    Profile aimed at maximizing speed.

  • HIGH

    Profile aimed at high-precision denoising.

  • LOW_COMPLEXITY

    Profile for content with low-complexity noise.

  • NORMAL

    Neutral profile.

  • VERY_NOISY

    Profile for very noisy content.

CUSTOM class-attribute instance-attribute

CUSTOM = 'custom'

Member for your own profile with no defaults.

FAST class-attribute instance-attribute

FAST = 'fast'

Profile aimed at maximizing speed.

HIGH class-attribute instance-attribute

HIGH = 'high'

Profile aimed at high-precision denoising.

LOW_COMPLEXITY class-attribute instance-attribute

LOW_COMPLEXITY = 'lc'

Profile for content with low-complexity noise.

NORMAL class-attribute instance-attribute

NORMAL = 'np'

Neutral profile.

VERY_NOISY class-attribute instance-attribute

VERY_NOISY = 'vn'

Profile for very noisy content.

Config dataclass

Config(
    profile: Profile,
    kwargs: KwargsT,
    basic_kwargs: KwargsT,
    final_kwargs: KwargsT,
    overrides: KwargsT,
    overrides_basic: KwargsT,
    overrides_final: KwargsT,
)

Profile config for arguments passed to the bm3d implementation basic/final calls.

Methods:

  • as_dict

    Get kwargs from this Config.

Attributes:

  • basic_kwargs (KwargsT) –

    Kwargs used for basic calls.

  • final_kwargs (KwargsT) –

    Kwargs used for final calls.

  • kwargs (KwargsT) –

    Base kwargs used for basic/final calls.

  • overrides (KwargsT) –

    Overrides for profile defaults and kwargs.

  • overrides_basic (KwargsT) –

    Overrides for profile defaults and kwargs for basic calls.

  • overrides_final (KwargsT) –

    Overrides for profile defaults and kwargs for final calls.

  • profile (Profile) –

    Which preset to use as a base.

basic_kwargs instance-attribute

basic_kwargs: KwargsT

Kwargs used for basic calls.

These can be overridden by overrides/overrides_basic or Profile defaults.

final_kwargs instance-attribute

final_kwargs: KwargsT

Kwargs used for final calls.

These can be overridden by overrides/overrides_final or Profile defaults.

kwargs instance-attribute

kwargs: KwargsT

Base kwargs used for basic/final calls.

These can be overridden by overrides or Profile defaults.

overrides instance-attribute

overrides: KwargsT

Overrides for profile defaults and kwargs.

overrides_basic instance-attribute

overrides_basic: KwargsT

Overrides for profile defaults and kwargs for basic calls.

overrides_final instance-attribute

overrides_final: KwargsT

Overrides for profile defaults and kwargs for final calls.

profile instance-attribute

profile: Profile

Which preset to use as a base.

as_dict

as_dict(
    cuda: Plugin | Literal[False],
    basic: bool = False,
    aggregate: bool = False,
    args: KwargsT | None = None,
    **kwargs: Any
) -> KwargsT

Get kwargs from this Config.

Parameters:

  • cuda
    (Plugin | Literal[False]) –

    Whether the implementation is cuda or not.

  • basic
    (bool, default: False ) –

    Whether the call is basic or final.

  • aggregate
    (bool, default: False ) –

    Whether it's an aggregate (refining) call or not.

  • args
    (KwargsT | None, default: None ) –

    Custom args that will take priority over everything else.

  • kwargs
    (Any, default: {} ) –

    Additional kwargs to add.

Returns:

  • KwargsT

    Dictionary of keyword arguments for the call.

Source code
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
def as_dict(
    self, cuda: vs.Plugin | Literal[False], basic: bool = False, aggregate: bool = False,
    args: KwargsT | None = None, **kwargs: Any
) -> KwargsT:
    """
    Get kwargs from this Config.

    :param cuda:        Whether the implementation is cuda or not.
    :param basic:       Whether the call is basic or final.
    :param aggregate:   Whether it's an aggregate (refining) call or not.
    :param args:        Custom args that will take priority over everything else.
    :param kwargs:      Additional kwargs to add.

    :return:            Dictionary of keyword arguments for the call.
    """

    kwargs |= self.kwargs

    if basic:
        kwargs |= self.basic_kwargs
    else:
        kwargs |= self.final_kwargs

    if self.profile is Profile.CUSTOM:
        values = KwargsT()
    elif not cuda:
        values = KwargsT(profile=self.profile.value)
    elif self.profile is Profile.VERY_NOISY:
        raise CustomValueError('Profile "VERY_NOISY" is not supported!', reason='BM3DCuda')
    else:
        if aggregate:
            if basic:
                PROFILES = {
                    Profile.FAST: KwargsT(block_step=8, bm_range=7, ps_num=2, ps_range=4),
                    Profile.LOW_COMPLEXITY: KwargsT(block_step=6, bm_range=9, ps_num=2, ps_range=4),
                    Profile.NORMAL: KwargsT(block_step=4, bm_range=12, ps_num=2, ps_range=5),
                    Profile.HIGH: KwargsT(block_step=3, bm_range=16, ps_num=2, ps_range=7),
                }
            else:
                PROFILES = {
                    Profile.FAST: KwargsT(block_step=7, bm_range=7, ps_num=2, ps_range=5),
                    Profile.LOW_COMPLEXITY: KwargsT(block_step=5, bm_range=9, ps_num=2, ps_range=5),
                    Profile.NORMAL: KwargsT(block_step=3, bm_range=12, ps_num=2, ps_range=6),
                    Profile.HIGH: KwargsT(block_step=2, bm_range=16, ps_num=2, ps_range=8),
                }
        else:
            if basic:
                PROFILES = {
                    Profile.FAST: KwargsT(block_step=8, bm_range=9),
                    Profile.LOW_COMPLEXITY: KwargsT(block_step=6, bm_range=9),
                    Profile.NORMAL: KwargsT(block_step=4, bm_range=16),
                    Profile.HIGH: KwargsT(block_step=3, bm_range=16),
                }
            else:
                PROFILES = {
                    Profile.FAST: KwargsT(block_step=7, bm_range=9),
                    Profile.LOW_COMPLEXITY: KwargsT(block_step=5, bm_range=9),
                    Profile.NORMAL: KwargsT(block_step=3, bm_range=16),
                    Profile.HIGH: KwargsT(block_step=2, bm_range=16),
                }

        values = PROFILES[self.profile]  # type: ignore[assignment]

    values |= kwargs | self.overrides

    if basic:
        values |= self.overrides_basic
    else:
        values |= self.overrides_final

    if args:
        values |= args

    if cuda:
        func = cuda.BM3Dv2 if hasattr(cuda, 'BM3Dv2') else cuda.BM3D
        cuda_keys = set[str](func.__signature__.parameters.keys())

        values = {
            key: value for key, value in values.items()
            if key in cuda_keys
        }

    return values

__call__

__call__(
    block_step: int | None = None,
    bm_range: int | None = None,
    block_size: int | None = None,
    group_size: int | None = None,
    bm_step: int | None = None,
    th_mse: float | None = None,
    hard_thr: float | None = None,
    ps_num: int | None = None,
    ps_range: int | None = None,
    ps_step: int | None = None,
    basic_kwargs: KwargsT | None = None,
    final_kwargs: KwargsT | None = None,
    **kwargs: Any
) -> Config
Source code
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
def __call__(
    self,
    block_step: int | None = None, bm_range: int | None = None,
    block_size: int | None = None, group_size: int | None = None,
    bm_step: int | None = None, th_mse: float | None = None, hard_thr: float | None = None,
    ps_num: int | None = None, ps_range: int | None = None, ps_step: int | None = None,
    basic_kwargs: KwargsT | None = None, final_kwargs: KwargsT | None = None, **kwargs: Any
) -> Profile.Config:
    return ProfileBase.Config(
        self, kwargs, basic_kwargs or {}, final_kwargs or {},
        {
            key: value for key, value in KwargsT(
                block_step=block_step, bm_range=bm_range, block_size=block_size,
                group_size=group_size, bm_step=bm_step, th_mse=th_mse
            ).items() if value is not None
        },
        {
            key: value for key, value in KwargsT(hard_thr=hard_thr).items() if value is not None
        },
        {
            key: value for key, value in KwargsT(
                ps_num=ps_num, ps_range=ps_range, ps_step=ps_step
            ).items() if value is not None
        }
    )

ProfileBase

Classes:

  • Config

    Profile config for arguments passed to the bm3d implementation basic/final calls.

Config dataclass

Config(
    profile: Profile,
    kwargs: KwargsT,
    basic_kwargs: KwargsT,
    final_kwargs: KwargsT,
    overrides: KwargsT,
    overrides_basic: KwargsT,
    overrides_final: KwargsT,
)

Profile config for arguments passed to the bm3d implementation basic/final calls.

Methods:

  • as_dict

    Get kwargs from this Config.

Attributes:

  • basic_kwargs (KwargsT) –

    Kwargs used for basic calls.

  • final_kwargs (KwargsT) –

    Kwargs used for final calls.

  • kwargs (KwargsT) –

    Base kwargs used for basic/final calls.

  • overrides (KwargsT) –

    Overrides for profile defaults and kwargs.

  • overrides_basic (KwargsT) –

    Overrides for profile defaults and kwargs for basic calls.

  • overrides_final (KwargsT) –

    Overrides for profile defaults and kwargs for final calls.

  • profile (Profile) –

    Which preset to use as a base.

basic_kwargs instance-attribute

basic_kwargs: KwargsT

Kwargs used for basic calls.

These can be overridden by overrides/overrides_basic or Profile defaults.

final_kwargs instance-attribute

final_kwargs: KwargsT

Kwargs used for final calls.

These can be overridden by overrides/overrides_final or Profile defaults.

kwargs instance-attribute

kwargs: KwargsT

Base kwargs used for basic/final calls.

These can be overridden by overrides or Profile defaults.

overrides instance-attribute

overrides: KwargsT

Overrides for profile defaults and kwargs.

overrides_basic instance-attribute

overrides_basic: KwargsT

Overrides for profile defaults and kwargs for basic calls.

overrides_final instance-attribute

overrides_final: KwargsT

Overrides for profile defaults and kwargs for final calls.

profile instance-attribute

profile: Profile

Which preset to use as a base.

as_dict

as_dict(
    cuda: Plugin | Literal[False],
    basic: bool = False,
    aggregate: bool = False,
    args: KwargsT | None = None,
    **kwargs: Any
) -> KwargsT

Get kwargs from this Config.

Parameters:

  • cuda
    (Plugin | Literal[False]) –

    Whether the implementation is cuda or not.

  • basic
    (bool, default: False ) –

    Whether the call is basic or final.

  • aggregate
    (bool, default: False ) –

    Whether it's an aggregate (refining) call or not.

  • args
    (KwargsT | None, default: None ) –

    Custom args that will take priority over everything else.

  • kwargs
    (Any, default: {} ) –

    Additional kwargs to add.

Returns:

  • KwargsT

    Dictionary of keyword arguments for the call.

Source code
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
def as_dict(
    self, cuda: vs.Plugin | Literal[False], basic: bool = False, aggregate: bool = False,
    args: KwargsT | None = None, **kwargs: Any
) -> KwargsT:
    """
    Get kwargs from this Config.

    :param cuda:        Whether the implementation is cuda or not.
    :param basic:       Whether the call is basic or final.
    :param aggregate:   Whether it's an aggregate (refining) call or not.
    :param args:        Custom args that will take priority over everything else.
    :param kwargs:      Additional kwargs to add.

    :return:            Dictionary of keyword arguments for the call.
    """

    kwargs |= self.kwargs

    if basic:
        kwargs |= self.basic_kwargs
    else:
        kwargs |= self.final_kwargs

    if self.profile is Profile.CUSTOM:
        values = KwargsT()
    elif not cuda:
        values = KwargsT(profile=self.profile.value)
    elif self.profile is Profile.VERY_NOISY:
        raise CustomValueError('Profile "VERY_NOISY" is not supported!', reason='BM3DCuda')
    else:
        if aggregate:
            if basic:
                PROFILES = {
                    Profile.FAST: KwargsT(block_step=8, bm_range=7, ps_num=2, ps_range=4),
                    Profile.LOW_COMPLEXITY: KwargsT(block_step=6, bm_range=9, ps_num=2, ps_range=4),
                    Profile.NORMAL: KwargsT(block_step=4, bm_range=12, ps_num=2, ps_range=5),
                    Profile.HIGH: KwargsT(block_step=3, bm_range=16, ps_num=2, ps_range=7),
                }
            else:
                PROFILES = {
                    Profile.FAST: KwargsT(block_step=7, bm_range=7, ps_num=2, ps_range=5),
                    Profile.LOW_COMPLEXITY: KwargsT(block_step=5, bm_range=9, ps_num=2, ps_range=5),
                    Profile.NORMAL: KwargsT(block_step=3, bm_range=12, ps_num=2, ps_range=6),
                    Profile.HIGH: KwargsT(block_step=2, bm_range=16, ps_num=2, ps_range=8),
                }
        else:
            if basic:
                PROFILES = {
                    Profile.FAST: KwargsT(block_step=8, bm_range=9),
                    Profile.LOW_COMPLEXITY: KwargsT(block_step=6, bm_range=9),
                    Profile.NORMAL: KwargsT(block_step=4, bm_range=16),
                    Profile.HIGH: KwargsT(block_step=3, bm_range=16),
                }
            else:
                PROFILES = {
                    Profile.FAST: KwargsT(block_step=7, bm_range=9),
                    Profile.LOW_COMPLEXITY: KwargsT(block_step=5, bm_range=9),
                    Profile.NORMAL: KwargsT(block_step=3, bm_range=16),
                    Profile.HIGH: KwargsT(block_step=2, bm_range=16),
                }

        values = PROFILES[self.profile]  # type: ignore[assignment]

    values |= kwargs | self.overrides

    if basic:
        values |= self.overrides_basic
    else:
        values |= self.overrides_final

    if args:
        values |= args

    if cuda:
        func = cuda.BM3Dv2 if hasattr(cuda, 'BM3Dv2') else cuda.BM3D
        cuda_keys = set[str](func.__signature__.parameters.keys())

        values = {
            key: value for key, value in values.items()
            if key in cuda_keys
        }

    return values