SharpenComplex2 source

From Avisynth wiki
Jump to: navigation, search

source: http://pastebin.com/bYCeusjT

# [insert rant about how I can't register on Doom9]
# port of MPC-HC's Sharpen Complex 2 to Avisynth
# http://forum.doom9.org/showthread.php?t=158385
# (I'm assuming it works correctly because MPC-HC refuses to run in Wine)
# previous version: http://pastebin.com/gamRgbgD
# only processes luma
# str0 is the non-edge unsharp amount, default 2.0
# str1 is the edge unsharp amount, default 1.125
# k0 is the non-edge blur kernel, default "3 14 3"
# k1 is the edge blur kernel, default "1 1 1"
# the kernels must have odd lengths (as required by mt_convolution)
# edgethr is the threshold for an edge on an arbitrary scale, default 0.2
# if debug is true, then the edge mask is returned instead
# for the stacked 16-bit version, there's no debug parameter
# lsb_in if true treats the input as a stacked 16-bit clip, default true
# lsb if true leaves the output as stacked 16-bit, otherwise it's dithered
# (output is the same format as the input by default)
# mode is for the DitherPost mode, default 0 (see Dither docs)
# recommendation: just use a regular unsharp filter, don't bother with this
# unless you're going to set the unsharp amount/kernels (in which case this
# script actually becomes useful; the default edge/non-edge filters are
# sufficiently similar to be pointless). the 16-bit version is an extra serving
# of pointlessness because it's almost visually identical to the 8-bit version
# with the default settings and it's significantly slower; it might be useful
# though, if the source is banding-prone or with non-default unsharp
# amounts/kernels.
# requirements: MaskTools v2 (for both the regular and 16-bit functions)
#               Dither package (16-bit only)

function SharpenComplex2(clip src,float "str0",float "str1",string "k0",string "k1",float "edgethr",bool "debug")
{

str0=default(str0,2.0)   # corresponds to CoefFlou
str1=default(str1,1.125) # corresponds to Sharpen_val1 * 9

k0=default(k0,"3 14 3") # ~ Gaussian blur with sigma^2=0.3
k1=default(k1,"1 1 1")  # ~ Gaussian blur with sigma^2=1/3=0.333...
#the 3 14 3 kernel is derived from assuming linear interpolation in the original
#code; you can set it to other kernels based on other interpolators, but bear in
#mind that blurrier interpolators lead to more sharpening

edgethr=default(edgethr,0.2) # corresponds to SharpenEdge

src

unsharp0=mt_lutxy(src,mt_convolution(k0,k0),"x x y - "+string(str0)+" * +",chroma="copy")
unsharp1=mt_lutxy(src,mt_convolution(k1,k1),"x x y - "+string(str1)+" * +")

sobelh=mt_convolution("-1 0 1","1 2 1",saturate=false,total=1.)
sobelv=mt_convolution("1 2 1","-1 0 1",saturate=false,total=1.)
edgemask=mt_lutxy(sobelh,sobelv,"x x * y y * + 0.5 ^ 255 / "+string(edgethr)+" > 255 0 ?")
default(debug,false) ? edgemask.grayscale : mt_merge(unsharp0,unsharp1,edgemask)

}

function SharpenComplex2_16(clip src,float "str0",float "str1",string "k0",string "k1",float "edgethr",bool "lsb_in",bool "lsb",int "mode")
{

str0=default(str0,2.0)
str1=default(str1,1.125)

k0="impulse "+default(k0,"3 14 3")
k1="impulse "+default(k1,"1 1 1")

edgethr=default(edgethr,0.2)

lsb_in=default(lsb_in,true)
lsb=default(lsb,lsb_in)

mode=default(mode,0)

lsb_in ? src : src.Dither_convert_8_to_16

o=last

w=width()
h=height()/2

blur0=Dither_resize16(w,h,kernel=k0,fh=-1,fv=-1,center=false,u=1,v=1)
blur1=Dither_resize16(w,h,kernel=k1,fh=-1,fv=-1,center=false,u=1,v=1)
unsharp0=Dither_add16(last,Dither_lut16(Dither_add16(last,Dither_lut16(blur0,"65535 x -"),dif=true),string(str0)+" x 32767 - * 32768 +"),dif=true)
unsharp1=Dither_add16(last,Dither_lut16(Dither_add16(last,Dither_lut16(blur1,"65535 x -"),dif=true),string(str1)+" x 32767 - * 32768 +"),dif=true)
#this is why Dither needs subtraction and multiplication utility functions

#edge mask computation doesn't require higher precision
#(more like there's no lutxy for 16-bit)
lsb_in?src.DitherPost(mode=-1):src
sobelh=mt_convolution("-1 0 1","1 2 1",saturate=false,total=1.)
sobelv=mt_convolution("1 2 1","-1 0 1",saturate=false,total=1.)
edgemask=mt_lutxy(sobelh,sobelv,"x x * y y * + 0.5 ^ 255 / "+string(edgethr)+" > 255 0 ?")

Dither_merge16_8(unsharp0,unsharp1,edgemask)
MergeLuma(o,last)

lsb ? last : DitherPost(mode=mode)

}
Personal tools