Log in

View Full Version : Psharpen using Masktools 2


ryrynz
1st August 2015, 07:30
Can Psharpen (http://forum.doom9.org/showthread.php?p=683344) be updated to use the latest Masktools 2?
I assume it'd be a fairly quick task changing a few functions etc.

colours
1st August 2015, 19:13
The conversion is pretty straightforward; all you need to do is to replace inpand/expand with mt_inpand/mt_expand, yv12subtract with mt_makediff, and yv12lutxy with mt_lutxy.

ryrynz
2nd August 2015, 02:49
The conversion is pretty straightforward; all you need to do is to replace inpand/expand with mt_inpand/mt_expand, yv12subtract with mt_makediff, and yv12lutxy with mt_lutxy.
Thanks. I did the inpand and expand changes but got stuck on the yv12subtract. Does the command itself stay the same? ie do I simply just cut and paste yv12subtract with mt_makediff?

colours
2nd August 2015, 07:42
I just checked the MaskTools v1 docs (probably should've done this before writing the first post) and apparently that's not quite right. (Four different calculation modes depending on the options?! v1 is pure insanity.)

function pSharpen (clip clp,
\int "strength", int "threshold",
\float "ss_x", float "ss_y",
\int "dest_x", int "dest_y")
{
# getting the input image size
ox = clp.width()
oy = clp.height()

# parsing the input values
strength = default(strength, 25)
threshold = default(threshold, 75)
ss_x = default(ss_x, 1.0)
ss_y = default(ss_y, 1.0)
dest_x = default(dest_x, ox)
dest_y = default(dest_y, oy)

strength = strength<0 ? 0 : strength>100 ? 100 : strength
threshold = threshold<0 ? 0 : threshold>100 ? 100 : threshold
ss_x = ss_x<1.0 ? 1.0 : ss_x
ss_y = ss_y<1.0 ? 1.0 : ss_y

# oversampling
val = ss_x!=1.0 || ss_y!=1.0 ?
\clp.lanczosresize(round(ox*ss_x/8)*8,round(oy*ss_y/8)*8) :
\clp

# calculating the max and min in every 3*3 square
max = val.mt_expand()
min = val.mt_inpand()

# normalizing max and val to values from 0 to (max-min)
nmax = average(max, 1, min, -1)
nval = average(val, 1, min, -1)

# initializing the strings used to obtain the output luma value
s = string(strength/100.0)
t = string(threshold/100.0)
x0 = string((threshold/100.0)*(1.0-strength/100.0)/(1.0-(1.0-threshold/100.0)*(1.0-strength/100.0)))
expr = \
"x y / 2 * 1 - abs "+x0+" < " +\
s+" 1 = " +\
"x y 2 / = 0 y 2 / ? " +\
"x y / 2 * 1 - abs 1 "+s+" - / " +\
"? " +\
"x y / 2 * 1 - abs 1 "+t+" - * "+t+" + " +\
"? " +\
"x y 2 / > 1 -1 ? * 1 + y * 2 /"

# calculates the new luma value pushing it towards min or max
nval = mt_lutxy(nval, nmax, expr)

# normalizing val to values from min to max
val = average(nval, 1, min, 1)

# applying the new luma value to the original clip &
# resizing the image to the output values
val = val.lanczosresize(dest_x, dest_y)
clp = clp.lanczosresize(dest_x, dest_y).mergeluma(val)

return clp
}

You'll need the Average plugin (https://github.com/tp7/Average) for this.

Edit (2016-03-07): changed dest_x/dest_y to be ints instead of floats.
Edit (2016-03-16): actually make it work when ss_x and ss_y are not both 1, because I broke the script when I originally ported it.

ryrynz
9th August 2015, 13:59
Working a treat, thank you very much!

Disturbance
1st March 2016, 06:12
Hi, I am trying to use the updated Masktools2 version on Win10, and I get this error when I try to use it in a script "

pSharpen(strength=25, threshold=75, ss_x=1.0, ss_y=1.0, dest_x=1.0, dest_y=1.0)

Script error: Invalid arguments to function 'lanczosresize'.
(C:/Program Files (x86)/AviSynth+/plugins64/pSharpen.avsi, line 60)
(D:\Downloads\Clip Output\Clip.avs, line 5)"

Line 60 being " clp = ss_x!=1.0 || ss_y!=1.0 || dest_x!=ox || dest_y!=oy ? clp.lanczosresize(dest_x,dest_y) : clp"
Line 5 being "pSharpen(strength=25, threshold=75, ss_x=1.0, ss_y=1.0, dest_x=1.0, dest_y=1.0)"

any thoughts on what could be causing that?

Disturbance
1st March 2016, 08:36
The width and height arguments of *Resize must be integer for obvious reason. So it's mysterious why dest_x and dest_y are declared as float type. It's also mysterious why you want the final result be resized to 1x1 size.

it was the example given on the "http://avisynth.nl/index.php/PSharpen" wiki for it, so that is what I tried to use ("pSharpen with default settings:"). The line 60 was from the avsi script.

Ok so just changing it to pSharpen() in the script at least lets it load. Just seems the example usage of the script should have added a bit of clarity to the line stating that the Dest_x+y should be the final video size. Thanks for pointing me in the right direction

Gavino
1st March 2016, 14:56
Just seems the example usage of the script should have added a bit of clarity to the line stating that the Dest_x+y should be the final video size.
The wiki page does say that dest_x and dest_y give the final image size.
However, it wrongly says they default to 1.0 - the defaults are the original input dimensions (see the code in post #4 above).

Like HolyWu, I am puzzled about them being declared as float, when they must be integers for the function to work properly.

Reel.Deel
1st March 2016, 15:09
The wiki page does say that dest_x and dest_y give the final image size.
However, it wrongly says they default to 1.0 - the defaults are the original input dimensions (see the code in post #4 above).


Fixed the wiki page. Thanks for pointing that out.

colours
7th March 2016, 10:13
Like HolyWu, I am puzzled about them being declared as float, when they must be integers for the function to work properly.

Fixed.

(I do not claim authorship over this script and will not be offering further fixes/changes for it.)

Selur
8th March 2016, 12:06
btw. using 'pSharpen(ss_x=2.00,ss_y=2.00)' causes a 'MergeLuma: Images must have same width and height!'-error
adding clp=val in line 26 at the end of the oversampling part seems to fix it:
function pSharpen (clip clp,
\int "strength", int "threshold",
\float "ss_x", float "ss_y",
\int "dest_x", int "dest_y")
{
# getting the input image size
ox = clp.width()
oy = clp.height()

# parsing the input values
strength = default(strength, 25)
threshold = default(threshold, 75)
ss_x = default(ss_x, 1.0)
ss_y = default(ss_y, 1.0)
dest_x = default(dest_x, ox)
dest_y = default(dest_y, oy)

strength = strength<0? 0 : strength>100? 100 : strength
threshold = threshold<0? 0 : threshold>100? 100 : threshold
ss_x = ss_x<1.0? 1.0 : ss_x
ss_y = ss_y<1.0? 1.0 : ss_y

# oversampling
val = ss_x!=1.0 || ss_y!=1.0 ?
\clp.lanczosresize(round(ox*ss_x/8)*8,round(oy*ss_y/8)*8) :
\clp
clp=val

# calculating the max and min in every 3*3 square
max = val.mt_expand()
min = val.mt_inpand()

# normalizing max and val to values from 0 to (max-min)
nmax = average(max,1,min,-1)
nval = average(val,1,min,-1)

# initializing the strings used to obtain the output luma value
s = string(strength/100.0)
t = string(threshold/100.0)
x0 = string((threshold/100.0)*(1.0-strength/100.0)/(1.0-(1.0-threshold/100.0)*(1.0-strength/100.0)))
expr = \
"x y / 2 * 1 - abs "+x0+" < " +\
s+" 1 = " +\
"x y 2 / = 0 y 2 / ? " +\
"x y / 2 * 1 - abs 1 "+s+" - / " +\
"? " +\
"x y / 2 * 1 - abs 1 "+t+" - * "+t+" + " +\
"? " +\
"x y 2 / > 1 -1 ? * 1 + y * 2 /"

# calculates the new luma value pushing it towards min or max
nval = mt_lutxy(nval,nmax,expr)

# normalizing val to values from min to max
val = average(nval,1,min,1)

# applying the new luma value to the original clip
clp = clp.mergeluma(val)

# resizing the image to the output values
clp = ss_x!=1.0 || ss_y!=1.0 || dest_x!=ox || dest_y!=oy ? clp.lanczosresize(dest_x,dest_y) : clp

return clp
}

StainlessS
8th March 2016, 20:12
This may behave differently in v2.58 and v2.6 (2.6 enforces eg conversion client supplied ss_x as int to type float, v2.58 will evaluate as int).


ss_x = default(ss_x, 1.0)
ss_y = default(ss_y, 1.0)



ss_x = Float(default(ss_x, 1.0))
ss_y = Float(default(ss_y, 1.0))

would make 2.58 and v2.6 behave the same.

EDIT: Whether the rest of the function behaves ok, I have no idea (I dont want to look at it any further).

colours
16th March 2016, 11:30
btw. using 'pSharpen(ss_x=2.00,ss_y=2.00)' causes a 'MergeLuma: Images must have same width and height!'-error
adding clp=val in line 26 at the end of the oversampling part seems to fix it

Fixed, because this was a bug I introduced while porting that seemingly no one ever noticed.

StainlessS: Nobody should still be using 2.5.8 or any earlier version when upgrading is as simple as stuffing a newer DLL in system32/syswow64. Don't suggest nonsolutions to nonproblems.

StainlessS
16th March 2016, 11:35
Nobody should still be using 2.5.8

Yeh well tell that to the people that are still using v2.57. (there are some)