View Full Version : Request: port avisynth mftoon2 to vapoursynth
ChaosKing
6th April 2017, 18:20
EDIT:
Download a bettter/fixed version of mfToon2 for vapoursynth here:
https://gist.github.com/Frechdachs/b3a05afe2f7d25316a10cf7239d53d0c
Thanks @Frechdachs, Myrsloik & WolframRhodium
---------------
Could someone be so kind and port this avisynth filter to vapoursynth?
http://avisynth.nl/index.php/MfToon
http://avisynth.nl/images/MfToon-v0.54.avsi
The dependencies are:
aWarpSharp2
MaskTools2
WarpSharp
This script uses Unsharpmask() and XSharpen() from warpsharp. What would be а vapoursynth equivalent for this?
You can find a Tweak() port here https://forum.doom9.org/showthread.php?t=172808
Thanks!
def mftoon2(clip, twidth=None, theight=None, ssw=4, ssh=4, xstren=255, xthresh=255, cwarp=True,
sharpen=True, strength=255, wdepth=16.0, wblur=1, wthresh=0.5, drange=64, dboost=1.0,
dlimit=30, debug=False, doutput=None, dclip=None, show=False, scolor="$FF00FF"):
return clip
##############################
## ##
## mfToon v0.52 by mf ^^; ##
## ##
## I would claim copyright, ##
## but as I do not give my ##
## real identity, I can't. ##
## So as netizen to net- ##
## izen, I ask you, please ##
## don't do lame stuff ##
## with my script, like ##
## claiming you made it. ##
## Thank you. ##
## ##
##############################
##############################
##
##
################################
################################
## ##
## Usage: ##
## ##
## Import("mfToon-v0.52.avs") ##
## mfToon() or mfToonLite() ##
## ##
################################
################################
####
##
## New maskbuilding ("cartoon" edgedetection), and mfToon-lite to use in realtime in your
## ffdshow "AVISynth" section. It's not meant for encoding, only playback.
##
##
function mfToon2(clip orig, int "twidth", int "theight", int "ssw", int "ssh", int "xstren", \
int "xthresh", bool "cwarp", bool "sharpen", int "strength", float "wdepth", int "wblur", \
float "wthresh", int "drange", float "dboost", int "dlimit", bool "debug", bool "doutput", \
string "dclip", bool "show", int "scolor") {
# normal params
strength = Default(strength, 255) # line darkening strength, 0-255
sharpen = Default(sharpen, true) # sharpening on/off
cwarp = Default(cwarp, true) # chroma warp on/off
cwarp2 = cwarp ? 1 : 0
wdepth = Default(wdepth, 16.0) # warping depth, ?-?
wblur = Default(wblur, 1) # warping blur level, ?-?
wthresh = Default(wthresh, 0.5) # warping threshold, 0.0-1.0
ssw = Default(ssw, 4) # supersample factor horizontally, 0-inf
ssh = Default(ssh, 4) # supersample factor vertically, 0-inf
twidth = Default(twidth, orig.width) # target width (useful for cropping), 0-inf
theight = Default(theight, orig.height) # target height (useful for cropping), 0-inf
show = Default(show, false) # show which lines are being darkened
scolor = Default(scolor, $FF00FF) # which color to show lines in
# advanced params
xstren = Default(xstren, 255) # xsharpening strength, 0-255
xthresh = Default(xthresh, 255) # xsharpening threshold, 0-255
## Where have all the params gone?! - They were useless as of 0.5, but I forgot to clean them.
drange = Default(drange, 64) # detail range, 0-255
dboost = Default(dboost, 1.0) # detail boost, 0.1-10.0
dlimit = Default(dlimit, 30) # detail limiter, 0-255
debug = Default(debug, false) # debug mode on/off
doutput = Default(doutput, true) # print debug info on processed image
dclip = Default(dclip, "rclip1") # which stage of the processing to show
ssw2 = twidth * ssw
ssh2 = theight * ssh
sharpen2 = show ? false : sharpen
orig.Unsharpmask(300, 4, 0)
sharp = last
mt_merge(sharp, orig, orig)
sharp1 = last
mt_merge(sharp1, orig, orig)
sharp2 = last
greymask = orig.mt_invert(u=-128, v=-128)
detailmaskpre0 = orig.mt_edge(thy1 = 3, thy2 = 255, thc1 = 255, thc2 = 255, mode = "cartoon", Y=3, V=1, U=1) \
.Tweak(0.0, 1.0, drange, 1.0).Levels(60, dboost, 255, 0, 255) \
.Levels(0, dboost, dlimit, 255, 0).mt_inflate(u=-128, v=-128).mt_deflate().mt_deflate().mt_deflate()
detailmaskpre1 = orig.mt_edge(thy1 = 3, thy2 = 255, thc1 = 255, thc2 = 255, mode = "roberts", Y=3, V=1, U=1) \
.Tweak(0.0, 1.0, drange, 1.0).Levels(60, dboost, 255, 0, 255) \
.Levels(0, dboost, dlimit, 255, 0).mt_inflate(u=-128, v=-128)
detailmaskpre2 = mt_lut(detailmaskpre1, "x x * x * x * 256 / 256 / 256 /").Blur(1.0).Levels(0, 1.0, 190, 0, 255)
mt_deflate()
detailmask = last
white = orig.mt_binarize(Y=-255,U=-128,V=-128)
linemask1 = mt_merge(white, detailmask, orig.mt_invert()).mt_invert()
linemask = (strength == 255) ? linemask1 : linemask1.levels(0, 1.0, 255, 0, strength)
color = BlankClip(orig, color=scolor)
sharp3 = show ? color : sharp2
dark = mt_merge(orig, sharp3, linemask, Y=3, U=1, V=1)
darkmerged = dark.MergeChroma(orig)
finaldark = show ? dark : darkmerged
semifinal=orig.BicubicResize(twidth, theight, 0, 0.75)
final = dark.BicubicResize(ssw2, ssh2, 0, 0.75).XSharpen(xstren, xthresh) \
.BicubicResize(twidth, theight, 0, 0.75).MergeChroma(semifinal) \
.aWarpSharp(cm=cwarp2, depth=wdepth, blurlevel=wblur, thresh=wthresh)
rclip1 = sharpen2 ? final : finaldark
Eval("dclip1 = doutput ? "+dclip+" : orig")
dstring1 = "mfToon v0.52 by mf - Debug mode ;p"
dstring2 = "Pointsized: DisabledxDisabled"
dstring3 = "Bicubicsized: " + String(ssw2) + "x" + String(ssh2)
dstring4 = "Outputsize: " + String(twidth) + "x" + String(theight)
dstring5 = "Debug image: " + dclip
clipstring = sharpen2 ? "final" : "finaldark"
dstring6 = "Output image: " + clipstring
dclip2 = dclip1.Subtitle(dstring1).Subtitle(dstring2, y=33).Subtitle(dstring3, y=48) \
.Subtitle(dstring4, y=63).Subtitle(dstring5, y=78).Subtitle(dstring6, y=93)
rclip2 = debug ? dclip2 : rclip1
return rclip2
}
Myrsloik
6th April 2017, 20:32
I checked the algorithm and you can implement XSharpen with minimum, maximum and expr. I'll post my version in a bit.
Unsharpmask is just a big radius blur with some thresholding as well. I think you'd need a box blur filter to make it fast but it should be possible to approximate with any other large radius blur.
Myrsloik
7th April 2017, 22:49
def Xsharpen(clip, strength = 128, threshold = 8):
return vs.core.std.Expr([clip, clip.std.Maximum(planes=0), clip.std.Minimum(planes=0)], ["y x - x z - min {} < x z - y x - < z y ? {} * x {} * + x ?".format(threshold, strength / 256, (256 - strength) / 256), ""])
Works on YUV, all formats.
Myrsloik
8th April 2017, 00:01
Bonus thing. Have fun porting!
def UnsharpMask(clip, strength = 64, radius = 3, threshold = 8):
blurclip = clip.std.Convolution([1] * (radius * 2 + 1), planes=0, mode="v")
blurclip = blurclip.std.Convolution([1] * (radius * 2 + 1), planes=0, mode="h")
return vs.core.std.Expr([clip, blurclip], ["x y - abs {} > x y - {} * x + x ?".format(threshold, strength/128), ""])
ChaosKing
8th April 2017, 09:07
Nice! Thank you, this helps a lot.
ChaosKing
8th April 2017, 14:30
So here is my first (alpha) port. It uses masktools2 from avisynth for now because I don't know all the vapoursynth "masktools" equivalents.
(I used an older masktools x64 build from here https://github.com/tp7/masktools/releases
the Avisynth+ masktools by pinterf https://github.com/pinterf/masktools/releases is chrashing immediately:
Plugin /coreplugins/AvsCompat.dll tried to register 'mt_invert' more than once.
Plugin /coreplugins/AvsCompat.dll tried to register 'mt_invert' more than once.
)
@Myrsloik Are Avisynth+ plugins supported by vapoursynth?
This gives me different results in avs and vp:
orig.Unsharpmask(300, 4, 0)
sharp = last
mt_merge(sharp, orig, orig)
VS
orig = UnsharpMask(clip, 300, 4, 0)
sharp = clip
clip = core.std.MaskedMerge(sharp, orig, orig) [OR clip = core.avs.mt_merge(sharp, orig, orig)]
The problem is the merge function. It seems like in doesn't merge it in vapoursynth like in avisynth.
http://i.imgur.com/jRRPPVD.jpg
I also noticed something... there is detailmaskpre0, detailmaskpre1, detailmaskpre2 in mftoon, but it is not used anywhere in the script later and slows down by a factor of 10 :devil:
When I uncomment the lines -> 13fps vs 150fps, same output. That's why the dboost parameter did nothing for me xD
Would this be a correct translation to vapoursynth?
mt_merge(sharp, orig, orig) -> clip = core.std.MaskedMerge(sharp, orig, orig)
dark.BicubicResize(ssw2, ssh2, 0, 0.75) ->dark.resize.Bicubic(ssw2, ssh2, filter_param_a = 0, filter_param_b = 0.75)
darkmerged = dark.avs.MergeChroma(orig) -> darkmerged = core.std.ShufflePlanes(clips=[dark, orig], planes=[0, 1, 2], colorfamily=clip.format.color_family)
This is my port so far (I tried to stay close to avisynth code, for now at least):
def mftoon2(clip, twidth=None, theight=None, ssw=4, ssh=4, xstren=255, xthresh=255, cwarp=True,
sharpen=True, strength=255, wdepth=16, wblur=1, wthresh=128, drange=64, dboost=1.0,
dlimit=30, debug=False, doutput=None, dclip=None, show=False, scolor="$FF00FF"):
#NOTE
#awarpsharp1 wthresh of 0.5 == 128 in awarpsharp2
#http://avisynth.nl/index.php/AWarpsharp2/aWarpSharp
cwarp2 = 0
if(cwarp):
cwarp2 = 1
ssw = 4 # supersample factor horizontally, 0-inf
ssh = 4 # supersample factor vertically, 0-inf
twidth = clip.width
theight = clip.height
ssw2 = twidth * ssw
ssh2 = theight * ssh
orig = UnsharpMask(clip, 300, 4, 0)
sharp = clip
clip = core.std.MaskedMerge(sharp, orig, orig)
#clip = core.avs.mt_merge(sharp, orig, orig)
sharp1 = clip
clip = core.std.MaskedMerge(sharp1, orig, orig)
#clip = core.avs.mt_merge(sharp1, orig, orig)
sharp2 = clip
graymask = orig.avs.mt_invert(U=-128, Y=-128) #NOT USED??
#graymask = core.std.ShufflePlanes(clip, 0, colorfamily=vs.GRAY)
#return graymask
#AVS
# Tweak( clip , float hue, float sat, float bright, float cont,
# bool coring, bool sse, float startHue, float endHue,
# float maxSat, float minSat, float interp, bool dither ] )
# Levels(clip input,
# int input_low, float gamma, int input_high,
# int output_low, int output_high
# [, bool coring , bool dither ] )
#
# std.Levels(clip clip[, float[] min_in, float[] max_in, float[] gamma=1.0, float[] min_out, float[] max_out, int[] planes=[0, 1, 2]])
#detailmaskpre0 = NOT USED??
d0 = orig.avs.mt_edge(thY1 = 3, thY2 = 255, thC1 = 255, thC2 = 255, mode = "cartoon", Y=3, V=1, U=1)
d0 = adjust.Tweak(d0, hue=0.0, sat=1.0, bright=drange, cont=1.0)
d0 = core.std.Levels(d0, min_in=60, gamma=dboost, max_in=255, min_out=0, max_out=255)
d0 = core.std.Levels(d0, min_in=0, gamma=dboost, max_in=dlimit, min_out=255, max_out=0)
detailmaskpre0 = d0.avs.mt_inflate(U=-128, V=-128).avs.mt_deflate().avs.mt_deflate().avs.mt_deflate()
d1 = orig.avs.mt_edge(thY1 = 3, thY2 = 255, thC1 = 255, thC2 = 255, mode = "roberts", Y=3, V=1, U=1)
d1 = adjust.Tweak(d1, hue=0.0, sat=1.0, bright=drange, cont=1.0)
d1 = core.std.Levels(d1, min_in=60, gamma=dboost, max_in=255, min_out=0, max_out=255)
d1 = core.std.Levels(d1, min_in=0, gamma=dboost, max_in=dlimit, min_out=255, max_out=0)
detailmaskpre1 = d1.avs.mt_inflate(U=-128, V=-128)
#Convolution(matrix=[1, 2, 1, 2, 4, 2, 1, 2, 1]) = blur(1)
#detailmaskpre2 = clip.avs.mt_lut(detailmaskpre1, "x x * x * x * 256 / 256 / 256 /").std.Convolution(matrix=[1, 2, 1, 2, 4, 2, 1, 2, 1]).std.Levels(d1, min_in=60, gamma=dboost, max_in=255, min_out=0, max_out=255)
clip = clip.avs.mt_deflate()
#clip = core.std.ShufflePlanes(clip, 0, colorfamily=vs.GRAY)
detailmask = clip
white = orig.avs.mt_binarize(Y=-255,U=-128,V=-128)
linemask1 = core.avs.mt_merge(white, detailmask, orig.avs.mt_invert()).avs.mt_invert()
linemask = core.std.Levels(linemask1, min_in=0, gamma=1.0, max_in=255, min_out=0, max_out=strength)
if(strength == 255):
linemask = linemask1
sharp3 = sharp2
dark = core.avs.mt_merge(orig, sharp3, linemask, Y=3, U=1, V=1)
darkmerged = core.std.ShufflePlanes(clips=[dark,orig], planes=[0, 1, 2], colorfamily=clip.format.color_family)#dark.avs.MergeChroma(orig)
finaldark = darkmerged
semifinal = orig.resize.Bicubic(twidth, theight, filter_param_a = 0, filter_param_b = 0.75) #, b=0, c=0.75 ??
final = dark.resize.Bicubic(ssw2, ssh2, filter_param_a = 0, filter_param_b = 0.75)
final = Xsharpen(final, xstren, xthresh)
final = final.resize.Bicubic(twidth, theight, filter_param_a = 0, filter_param_b = 0.75)
final = core.std.ShufflePlanes(clips=[final,semifinal], planes=[0, 1, 2], colorfamily=clip.format.color_family)#avs.MergeChroma(semifinal)
final = final.warp.AWarpSharp2(chroma=cwarp2, depth=wdepth, blur=wblur, thresh=wthresh)
return final
Are_
8th April 2017, 15:57
This gives me different results in avs and vp:
orig.Unsharpmask(300, 4, 0)
sharp = last
mt_merge(sharp, orig, orig)
VS
orig = UnsharpMask(clip, 300, 4, 0)
sharp = clip
clip = core.std.MaskedMerge(sharp, orig, orig) [OR clip = core.avs.mt_merge(sharp, orig, orig)]
I think you are mixing up some variables there, this part should be something like:
last = unsharpmask(clip, 300, 4, 0)
sharp = last
last = core.std.MaskedMerge(sharp, clip, clip)
sharp1 = last
last = core.std.MaskedMerge(sharp1, clip, clip)
sharp2 = last
But anyway mftoon52 and mftoon54 look like a mess, a lot of code looks like leftovers or just buggy.
ChaosKing
8th April 2017, 16:36
hmm will try it
I just found v52 with comments here https://forum.doom9.org/showthread.php?p=461851#post461851
This is missing in v54
## Add the two edgemasks together.
YV12Layer(detailmaskpre2, detailmaskpre2, "mul", 255, chroma=false, Y=3, V=1, U=1).Levels(0, 1.0, 190, 0, 255)
ConvertToYV12().Invert().Inflate().Invert()
detailmask = last
WolframRhodium
8th April 2017, 17:05
There's no need to use masktools of Avisynth for such code. Most of them can be implemented under vs standard library:
Take detailmaskpre0 as an example:
detailmaskpre0 = orig.std.Convolution([0, -2, 1, 0, 1, 0, 0, 0, 0], planes=[0]).std.Expr(['x 3 < 0 x ? 255 > 255 x ?', ''])
# mt_edge(thy1 = 3, thy2 = 255, thc1 = 255, thc2 = 255, mode = "cartoon", Y=3, V=1, U=1)
detailmaskpre0 = detailmaskpre0.std.Expr(['x {} + 16 max 235 min'.format(drrange), ''])
# Tweak(0.0, 1.0, drange, 1.0)
detailmaskpre0 = Levels(detailmaskpre0, 60, dboost, 255, 0, 255)
# Levels(60, dboost, 255, 0, 255)
# The Levels() function is at havsfunc (https://github.com/HomeOfVapourSynthEvolution/havsfunc/blob/master/havsfunc.py#L203)
detailmaskpre0 = Levels(detailmaskpre0, 0, dboost, dlimit, 255, 0)
# Levels(0, dboost, dlimit, 255, 0)
detailmaskpre0 = detailmaskpre0.std.Inflate(0)
# mt_inflate(u=-128, v=-128)
detailmaskpre0 = detailmaskpre0.std.Deflate(0).std.Deflate(0).std.Deflate(0)
# mt_deflate().mt_deflate().mt_deflate()
Or in short:
detailmaskpre0 = orig.std.Convolution([0,-2,1,0,1,0,0,0,0], planes=[0])
detailmaskpre0 = detailmaskpre0.std.Expr(['x 3 < 0 x ? {} + 16 max 235 min'.format(drrange), ''])
detailmaskpre0 = Levels(Levels(detailmaskpre0, 60, dboost, 255, 0, 255), 0, dboost, dlimit, 255, 0)
detailmaskpre0 = detailmaskpre0.std.Inflate(0).std.Deflate(0).std.Deflate(0).std.Deflate(0)
remaining code is similar:
detailmaskpre1 = orig.std.Convolution([0,0,0,0,2,-1,0,-1,0], divisor=2, saturate=False, planes=[0])
detailmaskpre1 = detailmaskpre1.std.Expr(['x 3 < 0 x ? {} + 16 max 235 min'.format(drrange), '']))
detailmaskpre1 = Levels(Levels(detailmaskpre1, 60, dboost, 255, 0, 255), 0, dboost, dlimit, 255, 0)
detailmaskpre1 = detailmaskpre1.std.Inflate(0)
detailmaskpre2 = detailmaskpre1.std.Expr(['x x * dup * 16777216 /', ''])
detailmaskpre2 = detailmaskpre2.rgvs.RemoveGrain([11, 0])
# Blur(1.0)
last = sharp2.std.Deflate(0)
detailmask = last
white = orig.std.BlankClip(color=[255, 128, 128])
# orig.mt_binarize(Y=-255,U=-128,V=-128)
linemask1 = white.std.MaskedMerge(detailmask, orig.std.Invert(0), planes=[0]).std.Invert(0)
linemask = linemask1 if strength == 255 else Levels(linemask1, 0, 1.0, 255, 0, strength)
I don't check the code above carefully, and it only works on YUV colorspace with 8 bits per sample, for simplicity.
ChaosKing
8th April 2017, 17:27
# Levels(60, dboost, 255, 0, 255)
# The Levels() function is at havsfunc
Does that mean std.Levels from Vapoursynth is different from the Avisynth Levels? Or why should I use Levels from havsfunc instead of the build-in one?
WolframRhodium
8th April 2017, 18:21
# Levels(60, dboost, 255, 0, 255)
# The Levels() function is at havsfunc
Does that mean std.Levels from Vapoursynth is different from the Avisynth Levels? Or why should I use Levels from havsfunc instead of the build-in one?
Levels() in havsfunc is almost a fully port of Avisynth's Levels() (except the parameter "dither")
core.std.Levels() is a equivalent to Levels(coring=True)
But by default, "coring" is False
In addition, current core.std.Levels() is much slower than Levels() in havsfunc, because the former one has no optimization on speed, while the later one uses core.std.Lut() and runs very fast.
Myrsloik
8th April 2017, 18:28
Just a general note about this. You can probably combine several of the levels abd tweak calls into a single expr at least. Those old scripts usually are a redundant mess.
WolframRhodium
8th April 2017, 18:49
Just a general note about this. You can probably combine several of the levels abd tweak calls into a single expr at least. Those old scripts usually are a redundant mess.
True,
but that would make the code even more messy, so I do not do that before
people with good knowledge on this can do it themselves
Frechdachs
8th April 2017, 23:54
I also noticed something... there is detailmaskpre0, detailmaskpre1, detailmaskpre2 in mftoon, but it is not used anywhere in the script later and slows down by a factor of 10 :devil:
When I uncomment the lines -> 13fps vs 150fps, same output. That's why the dboost parameter did nothing for me xD
Yes, the port to masktools2 is faulty, the detailmask evaluates to a sharpened version of the source clip which is obviously wrong. Apparently, in the past 11 years no one actually bothered to look at the code to see what this actually does.
Quick and dirty: Function (https://gist.github.com/Frechdachs/b3a05afe2f7d25316a10cf7239d53d0c)
Can probably be simplified but I dont't feel like wasting any more time on this shitty function.
I looked at the function before the masktools2 port and fixed the detailmask. Use legacy=True to get the behaviour of v0.54, but this is not recommended. Actually, you shouldn't use this function at all.
Works on any bitdepth.
Myrsloik
9th April 2017, 01:08
I think the argumebt scaling is wrong for xsharpen and unsharpmask.
Frechdachs
9th April 2017, 01:35
I think the argumebt scaling is wrong for xsharpen and unsharpmask.
What do you mean exactly?
Threshhold has to be scaled because it's compared to a difference and the difference will be bigger in 16 bit.
Given that
valuerange = (1 << clip.format.bits_per_sample)
maxvalue = valuerange - 1
Then
(x - y) * maxvalue // 255
equals
x * maxvalue // 255 - y * maxvalue // 255
And the strength value in Xsharpen is basically normalized before being inserted into the expression because it is divided by 256. Scaling strength and 256 to 16-bit would make no difference.
ChaosKing
9th April 2017, 02:04
Wow thank you Frechdachs.
I was just about to go to bed and then this :D
I made a quick test but noticed that the edges are kinda blurry.
see here (avisynth uses strength=100)
http://i.imgur.com/h9UZDdS.png
Frechdachs
9th April 2017, 02:46
Can't reproduce: https://diff.pics/AFmw9A7DgxNU/1
AviSynth and VapourSynth screens look exactly the same.
Are you sure, you imported the right function?
WolframRhodium
9th April 2017, 05:00
Quick and dirty: Function (https://gist.github.com/Frechdachs/b3a05afe2f7d25316a10cf7239d53d0c)
CartoonEdges() might be incorrect. In mt_edge(mode="cartoon"), the convolution kernel is [0,-2,1,0,1,0,0,0,0].
I verify it on masktools-v2.0a48, not only by checking the source code but also run a practical test.
Frechdachs
9th April 2017, 05:11
CartoonEdges() might be incorrect. In mt_edge(mode="cartoon"), the convolution kernel is [0,-2,1,0,1,0,0,0,0].
Edit: Disregard what was previously there, I misread your post.
I wrote this just with the information from there, never looked into the code: http://avisynth.nl/index.php/MaskTools2/Mt_edge
(Also did you get my PM? I don't see anything in "Sent Items".)
Edit2: Changed it.
WolframRhodium
9th April 2017, 05:48
(Also did you get my PM? I don't see anything in "Sent Items".)
Yes.
You can check "Save a copy of this message in your Sent Items folder." in "Additional Options" before sending PMs
Myrsloik
9th April 2017, 09:48
Never mind, it's just a brainfart.
ChaosKing
9th April 2017, 11:01
Can't reproduce: https://diff.pics/AFmw9A7DgxNU/1
AviSynth and VapourSynth screens look exactly the same.
Are you sure, you imported the right function?
Tried now with legacy=True: http://i.imgur.com/jMFkUMe.jpg
This is my code
orig= core.d2v.Source(input=r'D:\DVD_VIDEO\04.d2v', rff=True, nocrop =True)
clip = MfTurd(orig, strength=255, legacy=True)
clip2 = MfTurd(orig, strength=100, legacy=True)
clip3 = MfTurd(orig, strength=10, legacy=True)
a=280
#frame 36497
avi = core.avisource.AVISource(r"C:\Volumes\mf.avs\mf.avi")
return core.std.StackHorizontal([
core.std.CropRel(orig, a,a,0,0).text.Text("source"), \
core.std.CropRel(avi, a,a,0,0).text.Text("avisynth str=100"), \
core.std.CropRel(clip, a,a,0,0).text.Text("str=255 + legacy"), \
core.std.CropRel(clip2, a,a,0,0).text.Text("str=100 + legacy"), \
core.std.CropRel(clip3, a,a,0,0).text.Text("str=10 + legacy"), \
])
Here is the source frame I used http://i.imgur.com/KtFbSAP.png
Frechdachs
9th April 2017, 20:39
I converted your source image to YUV and still could not reproduce this, but I think I know what causes this problem for you:
Your DVD is interlaced, I assume. So first you should properly IVTC it and then call this:
clip = core.std.SetFrameProp(clip, prop='_FieldBased', intval=0)
Otherwise the internal resizer used within this function will resize it wrongly and cause this blurring.
ChaosKing
9th April 2017, 22:45
Indeed this was the cause. I didn't bother to ivtc it and just seeked to full frame for my test. Well no issues in avs :D
Again, a big Thank You to everyone.
And now with a better/fixed mask this problem ist also gone:
http://i.imgur.com/7quQcaL.png
Dark parts of the image had always "noise" with higher strength because of the broken masking as we now know.
Myrsloik
12th May 2017, 14:22
In R38 you can speed things up further by using BoxBlur:
def UnsharpMask(clip, strength = 64, radius = 3, threshold = 8):
blurclip = clip.std.BoxBlur(vradius=radius, hradius=radius, planes=0)
return vs.core.std.Expr([clip, blurclip], ["x y - abs {} > x y - {} * x + x ?".format(threshold, strength/128), ""])
ChaosKing
23rd May 2017, 20:22
Thanky You.
I made a small benchmark: UnsharpMask went from 48fps to 73fps. Nice speed up!
vBulletin® v3.8.11, Copyright ©2000-2025, vBulletin Solutions Inc.