WolframRhodium / muvsfunc

Muonium's VapourSynth functions
75 stars 19 forks source link

Cdeblend #23

Closed nobananasforyou closed 5 years ago

nobananasforyou commented 5 years ago

Hello,

Would you be so kind to port this to vs as well? Please let me know.

Thank you.

Script: http://avisynth.nl/images/Cdeblend.avs

WolframRhodium commented 5 years ago

Sorry, I'm busy now.

nobananasforyou commented 5 years ago

Okay.

WolframRhodium commented 5 years ago

As instructed in the documentation of C deblend, please use havsfunc.srestore() which is the successor of Cdeblend.

ghost commented 5 years ago

I tested it and it performs better than srestore and that's the reason I requested the port. Thank you for your time. Good day!

nobananasforyou commented 5 years ago

Ops, accidentally posted with another account.

WolframRhodium commented 5 years ago

Iwill take a look in the weekend.

WolframRhodium commented 5 years ago

Could you please check whether the following code works properly. (input: YUV, 8bit)

import mvsfunc as mvf
import havsfunc as haf

def Cdeblend(input, omode=0, bthresh=0.1, mthresh=0.6, xr=1.5, yr=2.0, fnr=False, dclip=None):
    assert isinstance(input, vs.VideoNode) and input.format.color_family == vs.YUV and input.format.bits_per_sample == 8

    blendclip = dclip if dclip is not None else input
    blendclip = mvf.GetPlane(blendclip, 0)
    blendclip = core.median.TemporalMedian(blendclip, radius=1)
    blendclip = core.resize.Bilinear(blendclip, int(blendclip.width * 0.125 / xr) * 8, int(blendclip.height * 0.125 / yr) * 8)

    diff = core.std.MakeDiff(blendclip, blendclip[1:])
    mask = core.std.Expr([diff, diff[1:]], [
        "x 128 - abs y 128 - abs < x 128 - abs x y + 256 - abs < and x 128 - abs x 128 - abs 0.5 pow - 2 pow y 128 - abs x y + 256 - abs < "
        "y 128 - abs y 128 - abs 0.5 pow - 2 pow x y + 256 - abs x y + 256 - abs 0.5 pow - 2 pow ? ? x 128 - y 128 - * 0 > -1 1 ? * 128 +"])

    Cbp3 = 128.0 if bthresh > 0 else 2.0
    Cbp2 = 128.0 if bthresh > 0 else 2.0
    Cbp1 = 128.0 if bthresh > 0 else 2.0
    Cbc0 = 128.0 if bthresh > 0 else 2.0
    Cbn1 = 128.0 if bthresh > 0 else 2.0
    Cbn2 = 128.0 if bthresh > 0 else 2.0

    Cdp3 = mthresh * 0.5
    Cdp2 = mthresh * 0.5
    Cdp1 = mthresh * 0.5
    Cdc0 = mthresh * 0.5
    Cdn1 = mthresh * 0.5

    current = 0

    def evaluate(n, f, clip):
        nonlocal Cdp3, Cdp2, Cdp1, Cdc0, Cdn1, Cbp3, Cbp2, Cbp1, Cbc0, Cbn1, Cbn2, current

        Cdiff = f[0].props["PlaneMAE"] * 255
        Cbval = f[1].props["PlaneMean"] * 255

        Cdp3 = Cdp2
        Cdp2 = Cdp1
        Cdp1 = Cdc0
        Cdc0 = Cdn1 if omode > 1 else Cdiff
        Cdn1 = Cdiff

        Cbp3 = Cbp2
        Cbp2 = Cbp1
        Cbp1 = Cbc0
        Cbc0 = Cbn1 if omode > 1 else (0.0 if Cdc0 < mthresh else (Cbval - Cbn2) / ((max(Cdc0, Cdp1) + mthresh) ** 0.8))
        Cbn1 = 0.0 if (Cdc0 < mthresh or Cdn1 < mthresh) else (Cbval - Cbn2) / ((max(Cdc0, Cdp1) + mthresh) ** 0.8)
        Cbn2 = Cbval

        current = (1 if ((Cbn1 < -bthresh and Cbc0 > bthresh) or (Cbn1 < 0 and Cbc0 > 0 and Cbc0 + Cbp1 > 0 and Cbc0 + Cbp1 + Cbp2 > 0)) else
                   0 if ((Cbc0 < -bthresh and Cbp1 > bthresh) or (Cbc0 < 0 and Cbc0 + Cbn1 < 0 and Cbp1 > 0 and Cbp1 + Cbp2 > 0)) else 
                   (2 if Cbn1 > 0 else 1) if current == -2 else 
                   current - 1)

        if omode == 2:
            current = (-1 if min(-Cbp1, Cbc0 + Cbn1) > bthresh and abs(Cbn1) > abs(Cbc0) else
                       1 if min(-Cbp2 - Cbp1, Cbc0) > bthresh and abs(Cbp2) > abs(Cbp1) else
                       -1 if min(-Cbp1, Cbc0) > bthresh else
                       0)

        if omode <= 1:
            current = (0 if min(-Cbp1, Cbc0) < bthresh else
                       -1 if omode == 0 else
                       1)

        if omode != 4:
            return clip[0:2] + clip[2+current:]
        else:
            text = f'{min(-Cbp1,Cbc0) if Cbc0 > 0 and Cbp1 < 0 else 0.0}{" -> BLEND!!" if min(-Cbp1, Cbc0) >= bthresh else " "}'
            return core.sub.Subtitle(clip, text)

    if omode > 1:
        # LumaDifference(blendclip.trim(1,0),blendclip.trim(3,0))
        Cdiff = mvf.PlaneCompare(blendclip[1:], blendclip[3:], mae=True, rmse=False, psnr=False, cov=False, corr=False)

        # AverageLuma(mask.trim(1,0))
        Cbval = mvf.PlaneStatistics(mask[1:], mean=True, mad=False, var=False, std=False, rms=False)
    else:
        # LumaDifference(blendclip,blendclip.trim(2,0)
        Cdiff = mvf.PlaneCompare(blendclip, blendclip[2:], mae=True, rmse=False, psnr=False, cov=False, corr=False)

        # AverageLuma(mask)
        Cbval = mvf.PlaneStatistics(mask, mean=True, mad=False, var=False, std=False, rms=False)

    last = core.std.FrameEval(input, functools.partial(evaluate, clip=input), prop_src=[Cdiff, Cbval])

    recl = haf.ChangeFPS(haf.ChangeFPS(last, last.fps_num * 2, last.fps_den * 2), last.fps_num, last.fps_den).std.Cache(make_linear=True)

    return recl

You may need to download vapoursynth-median.

nobananasforyou commented 5 years ago

Failed to evaluate the script: Python exception: No module named 'Cdeblend'

Traceback (most recent call last): File "src\cython\vapoursynth.pyx", line 1927, in vapoursynth.vpy_evaluateScript File "src\cython\vapoursynth.pyx", line 1928, in vapoursynth.vpy_evaluateScript File "D:/TESTSSSSSSSSS.vpy", line 2, in import Cdeblend as cd ModuleNotFoundError: No module named 'Cdeblend'

I've downloaded vs-median. Would you be able to add support for YUV422P8?

WolframRhodium commented 5 years ago

You can copy the code into your .vpy instead of importing it. YUV422P8 is supported.

nobananasforyou commented 5 years ago

It works, thanks. I think you also need to add 'import functools' at the top of the script to make it work.

WolframRhodium commented 5 years ago

Yes. It will be included in muvsfunc.py.