Log in

View Full Version : New Sharpening Function


*.mp4 guy
9th June 2010, 08:58
Examples : 4x nnedi2 (http://img709.imageshack.us/img709/9713/nnedi2.png), 4x nnedi2 New Sharpening (http://img97.imageshack.us/img97/8342/nnedi2blah.png), 4x nnedi2 limitedsharpenfaster smode4 (http://img690.imageshack.us/img690/9269/nnedi2lsf.png), 4x nnedi2 ssssharp (http://img687.imageshack.us/img687/3610/nnedi2sssharp.png).
Edit:Additional examples added, as requested.

After reading this post (http://forum.doom9.org/showthread.php?p=1358760#post1358760) by Didée I decided to
take a crack at the problem of sharpening an interpolated or lowpassed image. Out of curiosity I tried the resulting function
on a few difficult to sharpen non-interpolated sources (GITS R1 Special eddition, etc.), and it did very well (imo, of course).
So here is a new, general sharpening function. Right now its named "blah". Because naming things is difficult, and naming it
after what it is actually doing would require a paragraph long function call.

Function blah(Clip c, Int "str", int "strv", int "strh", float "de", float "dev", float "deh", float "re", float "rev", float "reh", float "cstr", float "cstrv", float "cstrh")
{# A sharpening function, Version 0.0

str = Default(Str, 4)
strv = Default(strv, str)
strh = Default(strh, str)
de = Default(de, 0.2)
dev = Default(dev, de)
deh = Default(deh, de)
re = Default(re, de/2)
rev = Default(rev, re)
reh = Default(reh, re)
cstr = Default(cstr, 0.5)
cstrv = Default(cstrv, cstr)
cstrh = Default(cstrh, cstr)

de = 20/de
dev = 20/dev
deh = 20/deh
re = 20/re
rev = 20/rev
reh = 20/reh

thrc = 72
thrcv = thrc
thrcH = thrc
thr2gv = 1/sqrt(thrcv)
thr2gh = 1/sqrt(thrch)


lp_V = C.NLLV_Variant4()
Diff_V = mt_makediff(C, lp_V)

lp_H = lp_V.NLLH_Variant4()
Diff_H = mt_makediff(lp_V, lp_H)
dev_ = string(rev)
deh_ = string(reh)
DeEmphasis = lp_H.yahr.yahr.Mt_Convolution(Horizontal=" 1 6 15 "+deh_+" 15 6 1 ", vertical =" 1 6 15 "+dev_+" 15 6 1 ", u=1, v=1)

STRV_ = string(strv)
Max_V = mt_luts( C, C, mode = "max", pixels = " 1 0 -1 0 ", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+STRV_+" 1 >= "+STRV_+" 0.5 ^ "+STRV_+" ? + / - 128 +", u=1, v=1)
Min_V = mt_luts( C, C, mode = "min", pixels = " 1 0 -1 0 ", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+STRV_+" 1 >= "+STRV_+" 0.5 ^ "+STRV_+" ? + / - 128 +", u=1, v=1)
MinMax_High_V = mt_lutXY( Max_V, Min_V, expr = "x 128 - abs y 128 - abs > x y ? 128 - abs", u=1, v=1)
MinMax_Low_V = mt_lutXY( Max_V, Min_V, expr = "x 128 - abs y 128 - abs > y x ? 128 - abs", u=1, v=1)
minmax_UL_V = mt_lutXY( MinMax_Low_V, MinMax_High_V, expr = "x y x - -", u=1, v=1)
minmax_G_V = Average(MinMax_High_V, 0.1, MinMax_Low_V, 0.35, minmax_UL_V, 0.275, minmax_UL_V, 0.275)
STRH_ = string(strh)
Max_H = mt_luts( C, C, mode = "max", pixels = " 0 1 0 -1 ", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+STRH_+" 1 >= "+STRH_+" 0.5 ^ "+STRH_+" ? + / - 128 +", u=1, v=1)
Min_H = mt_luts( C, C, mode = "min", pixels = " 0 1 0 -1 ", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+STRH_+" 1 >= "+STRH_+" 0.5 ^ "+STRH_+" ? + / - 128 +", u=1, v=1)
MinMax_High_H = mt_lutXY( Max_H, Min_H, expr = "x 128 - abs y 128 - abs > x y ? 128 - abs", u=1, v=1)
MinMax_Low_H = mt_lutXY( Max_H, Min_H, expr = "x 128 - abs y 128 - abs > y x ? 128 - abs", u=1, v=1)
minmax_UL_H = mt_lutXY( MinMax_Low_H, MinMax_High_H, expr = "x y x - -" )
minmax_G_H = Average(MinMax_High_H, 0.1, MinMax_Low_H, 0.35, minmax_UL_H, 0.275, minmax_UL_H, 0.275)


Diff_V = mt_lutXY( Diff_V, minmax_G_V, expr = " x 128 - y 1 > y 1 ? * y x 128 - abs - 1 > y x 128 - abs - 1 ? / 128 + ", u=1, v=1)
Diff_H = mt_lutXY( Diff_H, minmax_G_H, expr = " x 128 - y 1 > y 1 ? * y x 128 - abs - 1 > y x 128 - abs - 1 ? / 128 + ", u=1, v=1)
Diff_HV = mt_adddiff(Diff_H, Diff_V)
HPSharp = mt_adddiff(DeEmphasis, Diff_HV)
rev_ = string(rev)
reh_ = string(reh)
ReEmphasis = HPSharp.Mt_Convolution(Horizontal=" 1 6 15 -"+reh_+" 15 6 1 ", vertical =" 1 6 15 -"+rev_+" 15 6 1 ", u=1, v=1)

thrcv_ = string(thrcv)
V = MT_Luts(ReEmphasis, ReEmphasis, mode="med", pixels = " 0 0 0 1 0 -1 0 2 0 -2 " ,expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrcv_+" 1 >= "+thrcv_+" 0.5 ^ "+thrcv_+" ? + / - 128 +", u=1,v=1).mt_Lut("X 128 - abs", u=1, v=1)
thrch_ = string(thrch)
H = MT_Luts(ReEmphasis, ReEmphasis, mode="med", pixels = " 0 0 1 0 -1 0 2 0 -2 0 " ,expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrch_+" 1 >= "+thrch_+" 0.5 ^ "+thrch_+" ? + / - 128 +", u=1,v=1).mt_Lut("X 128 - abs", u=1, v=1)


Gauss_V = mt_Makediff(ReEmphasis, ReEmphasis.Mt_Convolution(Horizontal=" 1 ", vertical =" 1 6 15 20 15 6 1 ", u=1, v=1))
thr2gv_ = string(thr2gv)
cstrv_ = string(cstrv)
Gauss_V = mt_lutXY( Gauss_V, V, expr = " x 128 - y * "+thr2gv_+" * "+cstrv_+" * 128 + ", u=1, v=1)
Gauss_H = mt_Makediff(ReEmphasis, ReEmphasis.Mt_Convolution(Horizontal=" 1 6 15 20 15 6 1 ", vertical =" 1 ", u=1, v=1))
thr2gh_ = string(thr2gh)
cstrh_ = string(cstrh)
Gauss_H = mt_lutXY(Gauss_H, H, expr = " x 128 - y * "+thr2gh_+" * "+cstrh_+" * 128 + ", u=1, v=1)
Gauss_VH = mt_adddiff(Gauss_V, Gauss_H)
contrast = mt_adddiff(ReEmphasis, Gauss_VH)

Return(mergechroma(contrast, C, 1))
}

Required Functions:
Function blurH(clip c, int "rad", Float "CW")
{

Rad = Default(rad, 1)
CW = Default(CW, 0.5)

Center = C
Left = C.PointResize(C.width, C.height, -rad, 0, C.width, C.height)
Right = C.PointResize(C.width, C.height, rad, 0, C.width, C.height)

Average(Center, CW/2, Left, (1-CW)/2, Right, (1-CW)/2, Center, CW/2)

Return(last)
}

Function BlurV(clip c, int "rad", Float "CW")
{

Rad = Default(rad, 1)
CW = Default(CW, 0.5)

Center = C
Down = C.PointResize(C.width, C.height, 0, -rad, C.width, C.height)
Up = C.PointResize(C.width, C.height, 0, rad, C.width, C.height)

Average(Center, CW/2, Down, (1-CW)/2, Up, (1-CW)/2, Center, CW/2)

Return(last)
}

Function NLLH_Variant4(Clip C, int "rad")
{


Rad = Default(Rad, 1)

B1 = C.BlurH(1*rad, 0.439)
B2 = C.BlurH(2*rad, 0.833)
B3 = C.BlurH(3*rad, 0.934)
B4= C.BlurH(4*rad, 0.983)

B1_D = Mt_Makediff(B1, C, u=1, v=1)
B2_D = Mt_MakeDiff(C, B2, u=1, v=1)
B3_D = Mt_MakeDiff(B3, C, u=1, v=1)
B4_D = Mt_MakeDiff(C, B4, u=1, v=1)

B2_DT = Mt_LutXY(B1_D, B2_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 1.915 * X 128 - abs - 0 > \
Y 128 - abs 1.915 * X 128 - abs - 0 ? X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / + 128 + ", u=1, v=1)
B3_DT = Mt_LutXY(B2_DT, B3_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 2.025 * X 128 - abs - 0 > \
Y 128 - abs 2.025 * X 128 - abs - 0 ? X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / + 128 + ", u=1, v=1)
B4_DT = Mt_LutXY(B3_DT, B4_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 2.077 * X 128 - abs - 0 > \
Y 128 - abs 2.077 * X 128 - abs - 0 ? X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / + 128 + ", u=1, v=1)
Mt_AddDiff(B4_DT, C)



Return(last)
}

Function NLLV_Variant4(Clip C, int "rad")
{


Rad = Default(Rad, 1)

B1 = C.BlurV(1*rad, 0.439)
B2 = C.BlurV(2*rad, 0.833)
B3 = C.BlurV(3*rad, 0.934)
B4= C.BlurV(4*rad, 0.983)

B1_D = Mt_Makediff(B1, C, u=1, v=1)
B2_D = Mt_MakeDiff(C, B2, u=1, v=1)
B3_D = Mt_MakeDiff(B3, C, u=1, v=1)
B4_D = Mt_MakeDiff(C, B4, u=1, v=1)

B2_DT = Mt_LutXY(B1_D, B2_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 1.915 * X 128 - abs - 0 > \
Y 128 - abs 1.915 * X 128 - abs - 0 ? X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / + 128 + ", u=1, v=1)
B3_DT = Mt_LutXY(B2_DT, B3_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 2.025 * X 128 - abs - 0 > \
Y 128 - abs 2.025 * X 128 - abs - 0 ? X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / + 128 + ", u=1, v=1)
B4_DT = Mt_LutXY(B3_DT, B4_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 2.077 * X 128 - abs - 0 > \
Y 128 - abs 2.077 * X 128 - abs - 0 ? X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / + 128 + ", u=1, v=1)
Mt_AddDiff(B4_DT, C)



Return(last)
}

# Y'et A'nother H'alo R'educing script

function YAHR(clip clp)
{
b1 = clp.minblur(2).removegrain(11,-1)
b1D = mt_makediff(clp,b1)
w1 = clp.aWarpSharp(depth=32,blurlevel=2,thresh=0.5)
w1b1 = w1.minblur(2,1).removegrain(11,-1)
w1b1D = mt_makediff(w1,w1b1)
DD = b1D.repair(w1b1D,13)
DD2 = mt_makediff(b1D,DD)
clp.mt_makediff(DD2,U=2,V=2)
}

function MinBlur(clip clp, int r, int "uv")
{
uv = default(uv,3)
uv2 = (uv==2) ? 1 : uv
rg4 = (uv==3) ? 4 : -1
rg11 = (uv==3) ? 11 : -1
rg20 = (uv==3) ? 20 : -1
medf = (uv==3) ? 1 : -200

RG11D = (r==1) ? mt_makediff(clp,clp.removegrain(11,rg11),U=uv2,V=uv2)
\ : (r==2) ? mt_makediff(clp,clp.removegrain(11,rg11).removegrain(20,rg20),U=uv2,V=uv2)
\ : mt_makediff(clp,clp.removegrain(11,rg11).removegrain(20,rg20).removegrain(20,rg20),U=uv2,V=uv2)
RG4D = (r==1) ? mt_makediff(clp,clp.removegrain(4,rg4),U=uv2,V=uv2)
\ : (r==2) ? mt_makediff(clp,clp.medianblur(2,2*medf,2*medf),U=uv2,V=uv2)
\ : mt_makediff(clp,clp.medianblur(3,3*medf,3*medf),U=uv2,V=uv2)
DD = mt_lutxy(RG11D,RG4D,"x 128 - y 128 - * 0 < 128 x 128 - abs y 128 - abs < x y ? ?",U=uv2,V=uv2)
clp.mt_makediff(DD,U=uv,V=uv)
return(last)
}
Required plugins: Mt_Masktools, Average, Removegrain, aWarpSharp, Medianblur and Repair.

Defaults are intended for strong sharpening on 2x upscaled material. For normal sharpening, set de to 0.02, str to 3 and cstr
to 0.75 and go from there. The failure modes are as graceful as I can reasonably get them, considering the strength of the
sharpening required. Also, the degree of sharpening that can be "gotten away with" varies pretty wildly by source.

parameters:

str = strength of highpass sharpening default 4
strv = vertical version of str defaults to str
strh = horizontal version of str defaults to str

de = de-emphasis strength default 0.2
dev = vertical version of de defaults to de
deh = horizontal version of de defaults to de

re = re-emphasis strength defaults to de/2
rev = vertical version of re defaults to re
reh = horizontal version of re defaults to re

cstr = strength of contrast sharpening default 1, values above 1 will cause halos
cstrv = vertical version of cstr defaults to cstr
cstrh = horizontal version of cstr defaults to cstr

edit: thanks to Archimedes and Gavino for spotting two mistakes, both should now be fixed.
edit2: Changed non-linear lowpass function, new one should be generally more consistent

rkalwaitis
9th June 2010, 14:21
Medianblur function?

Archimedes
9th June 2010, 15:03
Requirements should be:
LoadPlugin("plugins\Average\src\Release\Average.dll")
LoadPlugin("plugins\aWarpSharp\aWarpSharp.dll")
LoadPlugin("plugins\MaskTools 2\mt_masktools.dll")
LoadPlugin("plugins\MedianBlur\medianblur.dll")
LoadPlugin("plugins\RemoveGrain 1.0\RemoveGrain.dll")
LoadPlugin("plugins\RemoveGrain 1.0\Repair.dll")

Gser
9th June 2010, 15:39
How about adding LSFmod and SSSharpen to the comparison?

Gavino
9th June 2010, 15:57
strv = Default(Str, 4)
strh = Default(Str, 4)
There's an obvious bug there; any values explicitly supplied for strv and strh are ignored and str used in their place. Should be
strv = Default(strv, str)
strh = Default(strh, str)

foxyshadis
10th June 2010, 00:43
I always like your style, mp4 guy. Keep throwing luts at the problem, pare it down to what works, figure out why and use that to start the process again. ;) I'll give this a shot tonight, though I have a feeling it's not going to work in realtime at all.

*.mp4 guy
10th June 2010, 23:43
Examples from GITS

MPEG2Source("K:\GITS_D1\VIDEO_TS\VTS_01_1.d2v", cpu=0, info=3).colormatrix(hints=true).crop(8, 16, -8, -16)
clip2=yadif()#mcbob.selecteven
TFM(slow=2, clip2=clip2, d2v="K:\GITS_D1\VIDEO_TS\VTS_01_1.d2v", pp=7)
tdecimate() (http://img62.imageshack.us/img62/2883/gitsnop.png)
MPEG2Source("K:\GITS_D1\VIDEO_TS\VTS_01_1.d2v", cpu=0, info=3).colormatrix(hints=true).crop(8, 16, -8, -16)
clip2=yadif()#mcbob.selecteven
TFM(slow=2, clip2=clip2, d2v="K:\GITS_D1\VIDEO_TS\VTS_01_1.d2v", pp=7)
tdecimate()

Mt_Convolution(Horizontal=" 1 6 15 -112 15 6 1 ", vertical =" 1 ", u=2, v=2)#horizontal unsharpmask

limitedsharpenfaster(smode=4, strength=100) (http://img59.imageshack.us/img59/9474/gitslsf.png)
MPEG2Source("K:\GITS_D1\VIDEO_TS\VTS_01_1.d2v", cpu=0, info=3).colormatrix(hints=true).crop(8, 16, -8, -16)
clip2=yadif()#mcbob.selecteven
TFM(slow=2, clip2=clip2, d2v="K:\GITS_D1\VIDEO_TS\VTS_01_1.d2v", pp=7)
tdecimate()

Mt_Convolution(Horizontal=" 1 6 15 -112 15 6 1 ", vertical =" 1 ", u=2, v=2)#horizontal unsharpmask

sssharp(denoise=0) (http://img243.imageshack.us/img243/7510/gitssssharp.png)
MPEG2Source("K:\GITS_D1\VIDEO_TS\VTS_01_1.d2v", cpu=0, info=3).colormatrix(hints=true).crop(8, 16, -8, -16)
clip2=yadif()#mcbob.selecteven
TFM(slow=2, clip2=clip2, d2v="K:\GITS_D1\VIDEO_TS\VTS_01_1.d2v", pp=7)
tdecimate()

Mt_Convolution(Horizontal=" 1 6 15 -112 15 6 1 ", vertical =" 1 ", u=2, v=2)#horizontal unsharpmask

blah(de=0.2, deh=0.025, rev=0.025, str=3, strh=12, cstrv=0.66, cstrh=1) (http://img821.imageshack.us/img821/1391/gitsblah.png)

Aster some testing I've switched out the non linear lowpass with a different variant (updated in first post). Also, If blah doesn't work for you guys, tell me now so I can see if its tunable, or if its just too fiddly to get good results. If you just don't like what it does, that's fine too. Basically what I want to know is if its usable for anyone else.

I'll give this a shot tonight, though I have a feeling it's not going to work in realtime at all. I was thinking about calling it epochsharpen, but I think its actually turned out faster then sssharp. It really pays to avoid that 4x supersampling, especially in RAM usage.

markanini
16th June 2010, 00:58
To my eyes blah has less haloing at the expense of less texture in relation to lsf and sssharp.

*.mp4 guy
16th June 2010, 03:22
To my eyes blah has less haloing at the expense of less texture in relation to lsf and sssharp.

When it sharpens texture it usually does it better imo, but it is less likely to sharpen texture then sssharp, and to an extent, lsf as well. However, I almost always prefer non-sharpened texture when doing upscaling as compared to what sssharp and lsf can do, so for me it is an all around improvement. The reduction in haloing is not directly linked to the difference in texture sharpening. It's possible to get similar texture sharpening from the underlying mechanisms, without halos, but its bad for other reasons.

Edit: Here is a question in return.

Is the reduction in sharpening strength good or bad in your opinion?

markanini
16th June 2010, 21:18
I mostly use sharpening in avsynth on upscaled still images via FritzPhoto, much like the examples you posted.
I found the lack of texture was a let down to be honest. Also it seem to overemphasize speckle like features and "stray pixels". But then it's remarkably immune to halos so I'll keep my eye on any developments.

*.mp4 guy
18th June 2010, 10:26
Alright, new spin off function. Pretty much just a general purpose sharpener now, but imo better then medsharp or sssharp. Also, better name then blah.


Function ReCon(clip c, float "str", float "strv", float "strh", float "rad", float "radh", float "radv", int "lmode", int "thresh")
{#Reconvolution - makes things sharp by mixing pixels together

str = Default(str, 4)
strv = Default(strv, str)
strh = Default(strh, str)

Rad = Default(Rad, 2)
Radv = Default(Radv, Rad)
Radh = Default(Radh, Rad)

lmode = Default(lmode, 1)

thresh = Default(thresh, 720)


thrc = thresh
thrcv = thrc
thrcH = thrc
thr2gv = 1/sqrt(thrcv)
thr2gh = 1/sqrt(thrch)
str_ = thresh
strv_ =str_
strh_ = str_

thrm = thresh

thrm_ = string(thrm)
Max_V = Radv == 0.5 ? mt_luts( C, C, mode = "max", pixels = "0 1 0 -1", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : C
Max_V = Radv == 1 ? mt_luts( C, C, mode = "max", pixels = "0 1 0 -1 0 2 0 -2", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Max_V
Max_V = Radv == 1.5 ? mt_luts( C, C, mode = "max", pixels = "0 1 0 -1 0 2 0 -2 0 3 0 -3", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Max_V
Max_V = Radv == 2 ? mt_luts( C, C, mode = "max", pixels = "0 1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Max_V
Max_V = Radv == 2.5 ? mt_luts( C, C, mode = "max", pixels = "0 1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4 0 5 0 -5", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Max_V
Max_V = Radv == 3 ? mt_luts( C, C, mode = "max", pixels = "0 1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4 0 5 0 -5 0 6 0 -6", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Max_V
Max_V = Radv == 4 ? mt_luts( C, C, mode = "max", pixels = "0 1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4 0 5 0 -5 0 6 0 -6 0 7 0 -7 0 8 0 -8", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Max_V

Min_V = Radv == 0.5 ? mt_luts( C, C, mode = "min", pixels = "0 1 0 -1", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : C
Min_V = Radv == 1 ? mt_luts( C, C, mode = "min", pixels = "0 1 0 -1 0 2 0 -2", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Min_V
Min_V = Radv == 1.5 ? mt_luts( C, C, mode = "min", pixels = "0 1 0 -1 0 2 0 -2 0 3 0 -3", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Min_V
Min_V = Radv == 2 ? mt_luts( C, C, mode = "min", pixels = "0 1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Min_V
Min_V = Radv == 2.5 ? mt_luts( C, C, mode = "min", pixels = "0 1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4 0 5 0 -5", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Min_V
Min_V = Radv == 3 ? mt_luts( C, C, mode = "min", pixels = "0 1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4 0 5 0 -5 0 6 0 -6", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Min_V
Min_V = Radv == 4 ? mt_luts( C, C, mode = "min", pixels = "0 1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4 0 5 0 -5 0 6 0 -6 0 7 0 -7 0 8 0 -8", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Min_V

thrcv_ = string(thrcv)
Med_V = Radv == 0.5 ? MT_Luts(C, C, mode="med", pixels = "0 0 0 1 0 -1" ,expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1,v=1) : C
Med_V = Radv == 1 ? MT_Luts(C, C, mode="med", pixels = "0 0 0 1 0 -1 0 2 0 -2" ,expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1,v=1) : Med_V
Med_V = Radv == 1.5 ? MT_Luts(C, C, mode="med", pixels = "0 0 0 1 0 -1 0 2 0 -2 0 3 0 -3" ,expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1,v=1) : Med_V
Med_V = Radv == 2 ? MT_Luts(C, C, mode="med", pixels = "0 0 0 1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4" ,expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1,v=1) : Med_V
Med_V = Radv == 2.5 ? MT_Luts(C, C, mode="med", pixels = "0 0 0 1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4 0 5 0 -5" ,expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1,v=1) : Med_V
Med_V = Radv == 3 ? MT_Luts(C, C, mode="med", pixels = "0 0 0 1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4 0 5 0 -5 0 6 0 -6" ,expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1,v=1) : Med_V
Med_V = Radv == 4 ? MT_Luts(C, C, mode="med", pixels = "0 0 0 1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4 0 5 0 -5 0 6 0 -6 0 7 0 -7 0 8 0 -8" ,expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1,v=1) : Med_V
Med_V = Med_V.mt_Lut("X 128 - abs", u=1, v=1)

MinMax_High_V = mt_lutXY( Max_V, Min_V, expr = "x 128 - abs y 128 - abs > x y ? 128 - abs", u=1, v=1)
MinMax_Low_V = mt_lutXY( Max_V, Min_V, expr = "x 128 - abs y 128 - abs > y x ? 128 - abs", u=1, v=1)
minmax_UL_V = mt_lutXY( MinMax_Low_V, MinMax_High_V, expr = "x y x - -", u=1, v=1)
minmaxmed_v = Average(MinMax_High_V, 0.0625, MinMax_Low_V, 0.25, minmax_UL_V, 0.34375, Med_V, 0.34375)

STRH_ = string(strh_)
Max_H = Radh == 0.5 ? mt_luts( C, C, mode = "max", pixels = "1 0 -1 0", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : C
Max_H = Radh == 1 ? mt_luts( C, C, mode = "max", pixels = "1 0 -1 0 2 0 -2 0", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Max_H
Max_H = Radh == 1.5 ? mt_luts( C, C, mode = "max", pixels = "1 0 -1 0 2 0 -2 0 3 0 -3 0", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Max_H
Max_H = Radh == 2 ? mt_luts( C, C, mode = "max", pixels = "1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4 0", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Max_H
Max_H = Radh == 2.5 ? mt_luts( C, C, mode = "max", pixels = "1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4 0 5 0 -5 0", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Max_H
Max_H = Radh == 3 ? mt_luts( C, C, mode = "max", pixels = "1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4 0 5 0 -5 0 6 0 -6 0", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Max_H
Max_H = Radh == 4 ? mt_luts( C, C, mode = "max", pixels = "1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4 0 5 0 -5 0 6 0 -6 0 7 0 -7 0 8 0 -8 0", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Max_H

Min_H = Radh == 0.5 ? mt_luts( C, C, mode = "min", pixels = "1 0 -1 0", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : C
Min_H = Radh == 1 ? mt_luts( C, C, mode = "min", pixels = "1 0 -1 0 2 0 -2 0", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Min_H
Min_H = Radh == 1.5 ? mt_luts( C, C, mode = "min", pixels = "1 0 -1 0 2 0 -2 0 3 0 -3 0", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Min_H
Min_H = Radh == 2 ? mt_luts( C, C, mode = "min", pixels = "1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4 0", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Min_H
Min_H = Radh == 2.5 ? mt_luts( C, C, mode = "min", pixels = "1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4 0 5 0 -5 0", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Min_H
Min_H = Radh == 3 ? mt_luts( C, C, mode = "min", pixels = "1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4 0 5 0 -5 0 6 0 -6 0", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Min_H
Min_H = Radh == 4 ? mt_luts( C, C, mode = "min", pixels = "1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4 0 5 0 -5 0 6 0 -6 0 7 0 -7 0 8 0 -8 0", expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1, v=1) : Min_H

thrch_ = string(thrch)
Med_H = Radh == 0.5 ? MT_Luts(C, C, mode="med", pixels = "0 0 1 0 -1 0" ,expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1,v=1) : C
Med_H = Radh == 1 ? MT_Luts(C, C, mode="med", pixels = "0 0 1 0 -1 0 2 0 -2 0" ,expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1,v=1) : Med_H
Med_H = Radh == 1.5 ? MT_Luts(C, C, mode="med", pixels = "0 0 1 0 -1 0 2 0 -2 0 3 0 -3 0" ,expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1,v=1) : Med_H
Med_H = Radh == 2 ? MT_Luts(C, C, mode="med", pixels = "0 0 1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4 0" ,expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1,v=1) : Med_H
Med_H = Radh == 2.5 ? MT_Luts(C, C, mode="med", pixels = "0 0 1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4 0 5 0 -5 0" ,expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1,v=1) : Med_H
Med_H = Radh == 3 ? MT_Luts(C, C, mode="med", pixels = "0 0 1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4 0 5 0 -5 0 6 0 -6 0" ,expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1,v=1) : Med_H
Med_H = Radh == 4 ? MT_Luts(C, C, mode="med", pixels = "0 0 1 0 -1 0 2 0 -2 0 3 0 -3 0 4 0 -4 0 5 0 -5 0 6 0 -6 0 7 0 -7 0 8 0 -8 0" ,expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+thrm_+" 1 >= "+thrm_+" 0.5 ^ "+thrm_+" ? + / - 128 +", u=1,v=1) : Med_H
Med_H = Med_H.mt_Lut("X 128 - abs", u=1, v=1)

MinMax_High_H = mt_lutXY( Max_H, Min_H, expr = "x 128 - abs y 128 - abs > x y ? 128 - abs", u=1, v=1)
MinMax_Low_H = mt_lutXY( Max_H, Min_H, expr = "x 128 - abs y 128 - abs > y x ? 128 - abs", u=1, v=1)
minmax_UL_H = mt_lutXY( MinMax_Low_H, MinMax_High_H, expr = "x y x - -" )
minmaxmed_h = Average(MinMax_High_h, 0.0625, MinMax_Low_h, 0.25, minmax_UL_h, 0.34375, Med_h, 0.34375)



Blur_V = C.NLLV_variant4()
Blur_V = Rad > 1 ? Blur_V.NLLV_variant4(2) : Blur_V
Blur_V = Rad > 2 ? Blur_V.NLLV_variant4(3) : Blur_V
Blur_V = Rad > 3 ? Blur_V.NLLV_variant4(4) : Blur_V
Sharp_Diff_V = mt_Makediff(C, Blur_V)

thr2gv_ = string(thr2gv)
cstrv_ = string(strv)
Sharp_V = lmode == 0 ? mt_lutXY(Sharp_Diff_V, minmaxmed_v, expr = " x 128 - y * "+thr2gv_+" * "+cstrv_+" * 128 + ", u=1, v=1) : C
Sharp_V = lmode == 1 ? mt_lutXY(Sharp_Diff_V, minmaxmed_v, expr = " x 128 - abs y > x 128 - y * "+thr2gv_+" * "+cstrv_+" * 128 + X 128 - y 0.5 ^ * "+thr2gv_+" 0.5 ^ * "+cstrv_+" * 128 + ? ", u=1, v=1) : Sharp_V
Sharp_V = lmode == 2 ? mt_lutXY(Sharp_Diff_V, minmaxmed_v, expr = " x 128 - abs y > x 128 - y * "+thr2gv_+" * "+cstrv_+" * 128 + Y 0 > X 128 - "+cstrv_+" * 128 + 128 ? ? ", u=1, v=1) : Sharp_V
Sharp_V = lmode == 3 ? mt_lutXY(Sharp_Diff_V, minmaxmed_v, expr = " x 128 - abs y > x 128 - y * "+thr2gv_+" * "+cstrv_+" * 128 + X 128 - "+cstrv_+" * 128 + ? ", u=1, v=1) : Sharp_V
Sharp_V = lmode == 4 ? mt_lutXY(Sharp_Diff_V, minmaxmed_v, expr = " x 128 - "+cstrv_+" * 128 + ", u=1, v=1) : Sharp_V

Blur_H = C.NLLH_variant4()
Blur_H = Rad > 1 ? Blur_H.NLLH_variant4(2) : Blur_H
Blur_H = Rad > 2 ? Blur_H.NLLH_variant4(3) : Blur_H
Blur_H = Rad > 3 ? Blur_H.NLLH_variant4(4) : Blur_H
Sharp_Diff_H = mt_Makediff(C, Blur_H)

thr2gh_ = string(thr2gh)
cstrh_ = string(strh)
Sharp_H = lmode == 0 ? mt_lutXY(Sharp_Diff_H, minmaxmed_h, expr = " x 128 - y * "+thr2gh_+" * "+cstrh_+" * 128 + ", u=1, v=1) : C
Sharp_H = lmode == 1 ? mt_lutXY(Sharp_Diff_H, minmaxmed_h, expr = " x 128 - abs y > x 128 - y * "+thr2gh_+" * "+cstrh_+" * 128 + X 128 - y 0.5 ^ * "+thr2gh_+" 0.5 ^ * "+cstrh_+" * 128 + ? ", u=1, v=1) : Sharp_H
Sharp_H = lmode == 2 ? mt_lutXY(Sharp_Diff_H, minmaxmed_h, expr = " x 128 - abs y > x 128 - y * "+thr2gh_+" * "+cstrh_+" * 128 + Y 0 > X 128 - "+cstrh_+" * 128 + 128 ? ? ", u=1, v=1) : Sharp_H
Sharp_H = lmode == 3 ? mt_lutXY(Sharp_Diff_H, minmaxmed_h, expr = " x 128 - abs y > x 128 - y * "+thr2gh_+" * "+cstrh_+" * 128 + X 128 - "+cstrh_+" * 128 + ? ", u=1, v=1) : Sharp_H
Sharp_H = lmode == 4 ? mt_lutXY(Sharp_Diff_H, minmaxmed_h, expr = " x 128 - "+cstrh_+" * 128 + ", u=1, v=1) : Sharp_H

Sharp_VH = mt_adddiff(Sharp_V, Sharp_H)
sharpened = mt_adddiff(C, Sharp_VH)
sharpened.mergechroma(C, 1)

Return(last)
}

Same depdendencies as blah, minus yahr and minblur related stuff.

Rad - radius of sharpening
str - strength
lmode - limit mode, 0 strong limiting, 3 minimal limiting. Default 1.

Also, I'm curious if rad 4 ever works better then rad 3.

update: added lmode 4

markanini
18th June 2010, 11:14
Hmm, no function named NLLV_variant4. What am I missing?
NEVERMIND: Missed the 'required functions' in OP.

markanini
19th June 2010, 17:17
Been testing Recon on a few web sized digicam and camera phone photos and I'm finding results are really pleasant and settings are simple and intuitive. I can see my self reachng for ReCon for most photos now. I'll still use lsfmod and sssharp for difficult sources and maximizing texture respectively. ReCon is in my eye the better general purpose sharpener now. Hats off for you *.mp4 guy!

markanini
20th June 2010, 06:42
I tested ReCon on a highly defocused digicam photo.

Scaled down to 1/6th for speedy processing and levels tweaked with smoothlevels:

http://img443.imageshack.us/img443/3676/dscn02690512x0384.jpg

With ReCon I settled on str=3, rad=28, lmode=2:
http://img541.imageshack.us/img541/3676/dscn02690512x0384.jpg

*.mp4 guy
20th June 2010, 07:33
Using a radius above 4 is not supported. If a radius above 4 is selected, mask generation is disabled (clip c is used instead). Radii above 4 are not supported because they become unusably slow, and the limiting method breaks down.

In this case, the blur is too much, and the limiting fails. In light of this I have added an unlimited mode, lmode=4, as upon further testing, the sharpening kernel performs better then unsharp masking on this source.

try theses settings with the updated version:
ReCon(rad=4, str=3, lmode=4)

Also, let me restate, rads that are not equal to 0.5, 1, 1.5, 2, 2.5, 3 or 4 do not function properly.

markanini
22nd June 2010, 07:32
I like the lmode range in the updated version !
I tried the blurry butterfly photo wih the new version was ab improvement. But I'm guessing you'd have to downscale that image further for a 4 pixel radius to fit....
Rather than talking about my special case I want to report that ReCon seems susceptible to alising in some sources, more so than lsfmod and sssharp.

markanini
22nd June 2010, 07:56
http://img12.imageshack.us/img12/2226/dscn02690512x03840512x0.jpg

Notice how transitions beteen white spots look cleaner in updated version.

Archimedes
22nd June 2010, 14:53
Rather than talking about my special case I want to report that ReCon seems susceptible to alising in some sources, more so than lsfmod and sssharp.
Seems, supersampling is needed. Normally, I don't like the results, when supersampling was used beforehand on normal sharpening tasks. That's why I prefer SSSharp(ssw=False) or SeeSaw for normal sharpening tasks (even with stronger settings you don't need any supersampling). But that's a question of personal taste.

However, on such blurred sources, antialiasing with supersampling afterwards (e. g. with NNEDI2) is not bad at all (if supersampling beforehand isn't a choice).

ReCon(rad=4, str=4, lmode=4) >> (http://img203.imageshack.us/img203/7181/dscn02690512x03840512x0.png)
ReCon(rad=4, str=4, lmode=4) + NNEDI2 + Spline36Resize >> (http://img85.imageshack.us/img85/7181/dscn02690512x03840512x0.png)

Didée
22nd June 2010, 15:41
Normally, I don't like the results, when supersampling was used beforehand on normal sharpening tasks.
There's always the possibility to perform supersampling without affecting the basic source by the supersampling process. It's not even much more difficult.

Instead of

source -> upsize -> filter -> downsize


one would do

1) source -> upsize -> filter
2) get difference(upsize,filtered)
3) source.apply(difference.downsize)

This way, the supersampling process affects only (well, mostly) the difference of the filter, not the source material in itself.

Archimedes
22nd June 2010, 16:53
Things can be so easy. :rolleyes: That will minimize the blur causing by the interpolation (up- and downscaling), indeed. But that's not the fly in the ointment (© http://www.leo.org). It's much more the "difference.downsize" which I dislike in combination with normal sharpening.

Archimedes
22nd June 2010, 19:17
Some Experiments.

Original (upscaled from 512x384 to 1024x768 with NNEDI3) >> (http://img714.imageshack.us/img714/5999/z3hs1n8ns1t1024x0768.png)

SSSharp >> (http://img189.imageshack.us/img189/5718/z3hs1n8ns1t1024x0768sss.jpg)
ReCon >> (http://img138.imageshack.us/img138/3410/z3hs1n8ns1t1024x0768rec.jpg)

Didée
22nd June 2010, 19:30
It's much more the "difference.downsize" which I dislike in combination with normal sharpening.
That implies you never downscale a [too-] large image to a smaller size? Because downscaling does necessarily look bad?

Perhaps the problem comes from using overly aggressive settings, which make the result look bad already at the supersampled stage, so much that the final downscale can't rescue the damage anymore ...

In case it's because of the inherent blurring that happens during downscaling - that effect can be combat'ed, too. Just highpass the downscaled difference before applying it.

*.mp4 guy
22nd June 2010, 20:38
There shouldn't be anything in ReCon that makes it produce more aliasing than an equivalent strength unsharpmask. Everything that inherently needs supersampling effectively already has it. The butterfly has aliasing because the sharpening settings used on it are of the same strength as unsharp(vary=4, str=6), which also produces aliasing.

The vast majority of the time ReCon is just sharpening aliasing that was already there. I can't prevent that without also preventing it from sharping details that occupy the same space.

If you look at the example image, you can see that the lines were not completely alias free before being sharpened. sssharp barely touches the lines, and doesn't reveal much aliasing. ReCon does sharpen the lines, and reveals aliasing. The two white dots indicate the places where ReCon actually screws up.

In case it's because of the inherent blurring that happens during downscaling - that effect can be combat'ed, too. Just highpass the downscaled difference before applying it. The inherent blurring would probably be the only thing causing giving aa in this case. Anyway, the correct thing to do would be to rework the sharpening kernel to avoid sharpening high frequencies, which would do the same thing. Only problem is that I want to sharpen the high frequencies.

foxyshadis
22nd June 2010, 21:05
The only thing that currently turns me off to ReCon relative to SSSharp is the way straight lines become dirty (looks like a cat chewed on them). Otherwise it's overall better. I looked at the problem but could think of no way to correct it without "correcting" most of the sharpening.

*.mp4 guy
22nd June 2010, 21:09
The only thing that currently turns me off to ReCon relative to SSSharp is the way straight lines become dirty (looks like a cat chewed on them). Otherwise it's overall better. I looked at the problem but could think of no way to correct it without "correcting" most of the sharpening.

Could you post a really bad example of this?

Archimedes
23rd June 2010, 17:15
Having problems with bright areas after sharpening (see branches in the middle of the pictures). To show the effect, I started with an aggressive setting (example 1). But the effect is also visible with a less aggressive setting (example 2).

Original >> (http://img191.imageshack.us/img191/5272/200704280024.png)
Example 1 >> (http://img819.imageshack.us/img819/6844/2007042800240800x0600re.jpg)
Example 2 >> (http://img819.imageshack.us/img819/7814/2007042800240800x0600ret.jpg)

rfmmars
23rd June 2010, 18:53
Having problems with bright areas after sharpening (see branches in the middle of the pictures). To show the effect, I started with an aggressive setting (example 1). But the effect is also visible with a less aggressive setting (example 2).

Original >> (http://img191.imageshack.us/img191/5272/200704280024.png)
Example 1 >> (http://img819.imageshack.us/img819/6844/2007042800240800x0600re.jpg)
Example 2 >> (http://img819.imageshack.us/img819/7814/2007042800240800x0600ret.jpg)

http://img718.imageshack.us/img718/8615/mypic10000.png (http://img718.imageshack.us/i/mypic10000.png/)

Uploaded with ImageShack.us (http://imageshack.us)

http://img710.imageshack.us/img710/9340/mypic20000.png (http://img710.imageshack.us/i/mypic20000.png/)

Uploaded with ImageShack.us (http://imageshack.us)

http://img203.imageshack.us/img203/3272/mypic30000.png (http://img203.imageshack.us/i/mypic30000.png/)

Uploaded with ImageShack.us (http://imageshack.us)
My try at them.

Undead Sega
31st December 2010, 01:48
Some Experiments.

Original (upscaled from 512x384 to 1024x768 with NNEDI3) >> (http://img714.imageshack.us/img714/5999/z3hs1n8ns1t1024x0768.png)

SSSharp >> (http://img189.imageshack.us/img189/5718/z3hs1n8ns1t1024x0768sss.jpg)
ReCon >> (http://img138.imageshack.us/img138/3410/z3hs1n8ns1t1024x0768rec.jpg)

SSSharpen never fails to amuse me, I wish I can see more examples or do them myself but I just dont know how to do so.

SilaSurfer
27th February 2011, 18:47
In case it's because of the inherent blurring that happens during downscaling - that effect can be combat'ed, too. Just highpass the downscaled difference before applying it.

Didée, could you elaborate please? I'm interested in combating blurring while downscaling from a 1080p Bluray sources. I know this is for Upsize->Filter->Downsamle, but I'm only Downsampling.

Jenyok
22nd December 2011, 10:14
Very interesting result (for me) is achieved using following code in following sequence (not another).
.

MCSharpening()
ReCon(str=4, rad=4, lmode=4) # various parameters

.
function MCSharpening(clip source)
http://forum.doom9.org/showthread.php?t=153170&page=3
.

function MCSharpening(clip source)
{
str = 1 # strength of predictionfilter, don't change

#source = last

#comment out tblurnl if you don't have residual low frequency blotchiness which fft3d loves to leave on everything
pred_ = Source.fft3dfilter(bw=6, bh=6, ow=3, oh=3, bt=1, sigma=str, plane=4). \
fft3dfilter(bw=216, bh=216, ow=108, oh=108, bt=1, sigma=str/8, sigma2=str/4, sigma3=str/2, sigma4=str, plane=4).TblurNL(rad=2, thresh=4)
pred = pred_.ttempsmooth(maxr=7).gradfun2db(1.01) #.hqdn3d(0.1, 0.1, 1.5, 1.5).gradfun2db(1.01) is faster and nearly as good, except on scene changes

super = pred.MSuper(pel=2, hpad=16, vpad=16, sharp=2)

backward_vec2 = MAnalyse(super, isb = true, delta = 2, overlap=4, truemotion=true, dct=5)
backward_vec1 = MAnalyse(super, isb = true, delta = 1, overlap=4, truemotion=true, dct=5)
forward_vec1 = MAnalyse(super, isb = false, delta = 1, overlap=4, truemotion=true, dct=5)
forward_vec2 = MAnalyse(super, isb = false, delta = 2, overlap=4, truemotion=true, dct=5)

maskp1 = Source.mmask(forward_vec1 ,kind=1, ysc=255).UtoY()
maskp2 = Source.mmask(forward_vec2 ,kind=1, ysc=255).UtoY()
maskp3 = Source.mmask(backward_vec1,kind=1, ysc=255).UtoY()
maskp4 = Source.mmask(backward_vec2,kind=1, ysc=255).UtoY()
maskf = average(maskp1, 0.25, maskp2, 0.25, maskp3, 0.25, maskp4, 0.25).spline36resize(source.width, source.height)

smooth = pred_.gradfun2db(1.01)
source2 = MT_Merge(source, smooth, maskf)

source3 = source2.MDegrain2(super, backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=400)
source3

# remove temporally blurred high frequency crud, can cause blocking upon reencode
VagueDenoiser(method=4, nsteps=10, wavelet=2, Wiener=true, auxclip=pred, percent=95, chromaT=1.0, wratio=0.75, threshold=0.5)

return gradfun2db(1.01)
}

.
ReCon(str=4, rad=4, lmode=4) # various parameters
http://forum.doom9.org/showthread.php?t=155030