def based_diff_mask(
clip: vs.VideoNode, ref_or_height: vs.VideoNode | int, kernel: KernelT = NoScale,
/,
thr: float = 0.216,
prefilter: int | KwargsT | bool | VSFunctionNoArgs[vs.VideoNode, ConstantFormatVideoNode] = False,
postfilter: Union[
int, tuple[Count, RemoveGrainMode],
list[tuple[Count, RemoveGrainMode]],
VSFunctionNoArgs[vs.VideoNode, ConstantFormatVideoNode]
] = 2,
ampl: str | type[EdgeDetect] | EdgeDetect = 'x yrange_max / 2 4 pow * {thr} < 0 1 ? yrange_max *',
expand: int = 4,
func: FuncExceptT | None = None
) -> ConstantFormatVideoNode:
func = func or based_diff_mask
assert check_variable(clip, func)
if isinstance(ref_or_height, vs.VideoNode):
ref = ref_or_height
else:
clip = get_y(clip)
kernel = Kernel.ensure_obj(kernel, func)
ref = kernel.descale(clip, get_w(ref_or_height), ref_or_height)
ref = kernel.scale(ref, clip.width, clip.height)
assert check_variable(ref, func)
if clip.format.num_planes != ref.format.num_planes:
clip, ref = get_y(clip), get_y(ref)
if prefilter:
if callable(prefilter):
clip, ref = prefilter(clip), prefilter(ref)
else:
if isinstance(prefilter, int):
sigma = 5 if prefilter is True else prefilter
kwargs = KwargsT(sigmaS=((sigma ** 2 - 1) / 12) ** 0.5, sigmaR=sigma / 10)
else:
kwargs = prefilter
clip, ref = bilateral(clip, **kwargs), bilateral(ref, **kwargs)
ref = depth(ref, clip)
dst_fmt = clip.format.replace(subsampling_w=0, subsampling_h=0)
diff_fmt = dst_fmt.replace(color_family=vs.GRAY)
mask = ExprOp.mae(dst_fmt)((Bilinear.resample(c, dst_fmt) for c in [clip, ref]), format=diff_fmt, split_planes=True)
mask = ColorRange.FULL.apply(mask)
if postfilter:
if isinstance(postfilter, int):
mask = iterate(mask, remove_grain, postfilter, RemoveGrainMode.MINMAX_AROUND2)
elif isinstance(postfilter, tuple):
mask = iterate(mask, remove_grain, postfilter[0], postfilter[1])
elif isinstance(postfilter, list):
mask = mask
for count, rgmode in postfilter:
mask = iterate(mask, remove_grain, count, rgmode)
else:
mask = postfilter(mask)
if isinstance(ampl, str):
mask = norm_expr(mask, ampl.format(thr=thr), func=func)
else:
mask = EdgeDetect.ensure_obj(ampl, func).edgemask(mask, lthr=thr, hthr=thr)
if expand:
mask = Morpho.expand(mask, expand, mode=XxpandMode.ELLIPSE, func=func)
return mask