Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.


Go Back   Doom9's Forum > Capturing and Editing Video > VapourSynth

Thread Tools Search this Thread Display Modes
Old 20th September 2015, 12:43   #1  |  Link
Pig on the wing
Boulder's Avatar
Join Date: Mar 2002
Location: Hollola, Finland
Posts: 4,924
Contrasharpening HD for Vapoursynth, optimization issue

This is supposed to work like the HD mod of ContraSharpen. With 16-bit clips it takes a very long time to initialize - do you see what needs to be changed? Any other modifications are of course welcome

import vapoursynth as vs
import havsfunc as has

def ContraSharpeningHD(denoised, original, cb1, cf1, superclip, thscd1=300, thscd2=80):
    core = vs.get_core()
    if denoised.format.id != original.format.id:
        raise ValueError('ContraSharpening: clips must have the same format')
    if denoised.format.color_family != vs.GRAY:
        denoised_src = denoised
        denoised_src = None
    cb1 = core.mv.Compensate(original,superclip,cb1,thscd1=thscd1,thscd2=thscd2)
    cf1 = core.mv.Compensate(original,superclip,cf1,thscd1=thscd1,thscd2=thscd2)
    pmax = core.std.Expr([original, cb1], expr=['x y max'])
    pmax = core.std.Expr([pmax, cf1], expr=['x y max'])
    pmin = core.std.Expr([original, cb1], expr=['x y min'])
    pmin = core.std.Expr([pmin, cf1], expr=['x y min'])
    s = has.MinBlur(denoised, 2, planes=[0])                                    
    allD = core.std.MakeDiff(original, denoised,planes=[0])                
    ssD = core.std.MakeDiff(s, core.rgvs.RemoveGrain(core.rgvs.RemoveGrain(s, [20,0]),[20,0]),planes=[0])  
    ssD2 = core.rgvs.Repair(ssD, allD, [1,0])                     
    ssDD = core.rgvs.Repair(ssD, ssD2, [12,0])
    expr = 'x {median} - abs y {median} - abs < x y ?'.format(median=1<<(denoised.format.bits_per_sample-1))
    ssDD = core.std.Expr([ssDD, ssD], [expr])                   
    last = core.std.MergeDiff(denoised, ssDD, planes=[0])                   
    last = core.std.Interleave(clips=[last, pmin, pmax])
    last = core.rgvs.Clense(last,planes=[0])
    last = core.std.SelectEvery(last, cycle=3, offsets=1)
    if denoised_src is not None:
        return core.std.ShufflePlanes([last, denoised_src], planes=[0, 1, 2], colorfamily=denoised_src.format.color_family)
        return last
The original function (from SMDegrain):
FUNCTION ContraSharpeningHD(clip denoised, clip original, bool "HD", bool "planar", int "overshoot"){
HD        = default(HD    ,false)
planar    = default(planar,false)
overshoot = default(overshoot,0)

HD ? eval("""
cb1=original.MCompensate(Super, cb1, planar=planar)
cf1=original.MCompensate(Super, cf1, planar=planar)
pmax = original.mt_logic(cb1, "max").mt_logic(cf1, "max")
pmin = original.mt_logic(cb1, "min").mt_logic(cf1, "min")""") : nop()

s    = denoised.MinBlur(HD?2:1,1,planar=planar)                                   # Damp down remaining spots of the denoised clip.
allD = mt_makediff(original,denoised)                                             # The difference achieved by the denoising.
ssD  = mt_makediff(s,HD?s.removegrain(20,-1,planar=planar).\
                        s.removegrain(11,-1,planar=planar))                       # The difference of a simple kernel blur.
ssDD = ssD.repair(HD?ssD.repair(allD,1,planar=planar):allD,HD?12:1,planar=planar) # Limit the difference to the max of what the denoising removed locally.
ssDD = SSDD.mt_lutxy(ssD,"x 128 - abs y 128 - abs < x y ?")                       # abs(diff) after limiting may not be bigger than before.

denoised.mt_adddiff(ssDD,U=2,V=2)                                                 # Apply the limited difference. (Sharpening is just inverse blurring)
HD ? mt_clamp(last,pmax,pmin,overshoot,overshoot,chroma="copy first") : last
And if the band you're in starts playing different tunes
I'll see you on the dark side of the Moon...
Boulder is offline   Reply With Quote
Old 20th September 2015, 19:32   #2  |  Link
Registered User
HolyWu's Avatar
Join Date: Aug 2006
Location: Taiwan
Posts: 755
Because MinBlur(2) will use CTMF for median blur of radius 2. Unfortunely the algorithm of CTMF is propably not suitable for 16-bit calculation. The "memsize" parameter of CTMF is defaulted to 1048576 (1MB). You can modify the MinBlur function in HAvsFunc and set that argument to the largest cache size of your CPU (probably will be the L3 cache on modern CPUs), then it may run a bit faster, but still a lot slower than performing on 12-bit clip. Alternatively, you may replace MinBlur(2) with sbr(2) and see if it still works as expected.
HolyWu is offline   Reply With Quote
Old 20th September 2015, 19:51   #3  |  Link
Pig on the wing
Boulder's Avatar
Join Date: Mar 2002
Location: Hollola, Finland
Posts: 4,924
Thanks, I'll give sbr a shot. It shouldn't make that much of a difference since it's really just a blur
And if the band you're in starts playing different tunes
I'll see you on the dark side of the Moon...
Boulder is offline   Reply With Quote
Old 21st September 2015, 02:02   #4  |  Link
I'm Siri
feisty2's Avatar
Join Date: Oct 2012
Location: Providence, RI
Posts: 2,376
Kinda different
Minblur is... Nonlinear, so, ringing free
Sbr is linear last time I checked
If I got new ideas, will post here: https://github.com/IFeelBloated
feisty2 is offline   Reply With Quote

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

All times are GMT +1. The time now is 21:34.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2020, vBulletin Solutions Inc.