View Full Version : MaskTools 2.0a48
Pages :
1
[
2]
3
4
5
6
7
8
9
10
11
12
13
mg262
29th October 2005, 13:11
Quick thought for the lookup table functions: as an alternative to using a string, would it be possible to take the name of a AVISynth function like
function myfunction(int argument) #returns an integer
or
function myfunction(int first, int second) #returns an integer
And using Invoke repeatedly, build up the lookup table?
Manao
29th October 2005, 13:54
mg262 : why do you want to use avisynth functions for ? or better put, what is missing in mt_lut that I could add
@all : a new version is up, fixing the mt_polish helper ( it was having some problem with functions ) :
http://manao4.free.fr/masktools-v2.0a6.zip
mg262
29th October 2005, 18:35
Nested repeated subexpressions. For example, min(x,y) :
x y < x y ?
(I think!) This kind of thing crops up a lot in scripts, especially Didée's. In itself it is not a problem, but when these things start being nested then the string length grows exponentially for obvious reasons.
In particular, I wanted to write a filter that worked on masks of luma differences; often these are represented by adding 128, but there are advantages to using signed bytes, both for speed and simplicity. Because the input mask would nearly always come from YV12LUT, the unsigned to signed conversion could be incorporated at no speed cost -- but because you need to be careful about overflow, the resultant string could become so long that it was difficult to check its correctness.
what is missing in mt_lut that I could add
min and max would help a bit? (lambda expressions would solve everything, but that's expecting a bit much!)
Don't worry about this one too much -- I can always do the signed<-->unsigned+128 conversion in separate filter.
Manao
29th October 2005, 18:53
function min(string x, string y)
{
return "(" + x + ") < (" + y + ") ? (" + x + ") : (" + y + ")"
}
function max(string x, string y)
{
return "(" + x + ") > (" + y + ") ? (" + x + ") : (" + y + ")"
}
my_expr = min(max("x", "y"), "x")
my_expr = mt_polish(my_expr)
return messageclip(my_expr)lambda expressions would solve everythingCan you be a little more specific ? you'd want to be able to define functions in order to use them in the expression ?
Edit : BTW, the string generated for min(max(x, y), x) is x y > x y ? x < x y > x y ? x ?So, indeed, min & max might prove usefull :P
mg262
29th October 2005, 19:13
String functions will solve things nicely. Thank you!
lambda expressions would solve everythingThat wasn't really meant to be a serious suggestion -- sorry if it came across that way. Looking at postfix/prefix expressions always reminds me of LISP and variants,* which lets you create anonymous functions in the middle of expressions like this: (lambda (arg) (/ arg 50)) -- that term can be used just like any built-in function (e.g. cos). So you could write (cos 20) or ((lambda (arg) (/ arg 50)) 20). I wasn't seriously suggesting that you add something like this though -- it is not clearly necessary in this context.
*prefix not postfix, but the equivalence will be fairly clear.
I will create an appropriate string function -- probably directly postfix rather than using mt_polish. Thank you for the solution.
Didée
30th October 2005, 04:02
There seems to be a bug in the parser. On my side, multi-letter operators are not working.
last.mt_lut("x 128 - abs")
All of those "abs", "sin" and whatnotelse throw a "lut: invalid yexpr" and similar. Both for lut and lutxy.
Didn't work for me in a5, and doesn't in a6.
Manao
30th October 2005, 08:10
Fixed ( i forgot to make the parser aware of the functions :) )
Didée
30th October 2005, 10:56
Yup, much better now. Thanks a lot :)
Oh, and your signature is outdated. Still links to MT 2.0a5.
Manao
30th October 2005, 11:03
What would I do without you ? Oh, yeah, sleep :D
Socio
3rd November 2005, 02:58
unskinnyboy - read the txt in the package, it cannot work out-of-the-box. All filter names have changed, so you'd have to edit all calls to MaskTools' filters in LS by yourself.
Kind of OT:
Well I am thoroughly confused with Mano's new naming structure, there is no function called DEdgeMask. There is a function called " mt_edge" which along with mt_motion and mt_mapped "are the counterpart of EdgeMask,
DEdgeMask, DEdgeMask2 and MotionMask".
I tried changing the calls in LS from DEdgeMask to mt_edge and it did not work, so what function call do you use to replace DEdgeMask in LS?
EDIT: Didee it looks like you may need to completely re-write your DEdgeMask call in LS to make this new version of masktools work.
foxyshadis
3rd November 2005, 03:25
Kind of OT:
Well I am thoroughly confused with Mano's new naming structure, there is no function called DEdgeMask. There is a function called " mt_edge" which along with mt_motion and mt_mapped "are the counterpart of EdgeMask,
DEdgeMask, DEdgeMask2 and MotionMask".
I tried changing the calls in LS from DEdgeMask to mt_edge and it did not work, so what function call do you use to replace DEdgeMask in LS?
EDIT: Didee it looks like you may need to completely re-write your DEdgeMask call in LS to make this new version of masktools work.
Just replace with mt_edge(mode="custom matrix",y1=....). The main change is that edgemask and dedgemask were merged, mode replaces both type and matrix. If there's a divisor, it's appended to the end of the custom matrix.
mt_mapped is dedgemask2 equivalent, I guess, replacing the y/c arguments with special clips.
Socio
6th November 2005, 19:30
I got it working in LS took a litle more than just subing the names though thx for the help foxyshadis.
I have another question does the "mt" prefix in the new function names stand for multi threading?
Manao
6th November 2005, 19:33
No, it's a shortcut for MaskTools. Since both version ( v1 and v2 ) had to be usable at the same time, I had to differenciate them.
Manao
7th November 2005, 23:10
*Bump*
New build is up : http://manao4.free.fr/masktools-v2.0a8.zip
Changes from alpha 7 to alpha 8 : * fixed : mt_edge in custom mode wasn't working properly
* fixed : mt_edge in custom mode, optimized wasn't working properly either
* fixed : mt_lutxy was slow to load, it's better now
AVIL
8th November 2005, 20:51
@manao
mt_convolution don't work for me
myclip.mt_convolution(horizontal="0 1 0", vertical="-1 2 -1",u=3,v=3) left myclip x untouched.
myclip.yv12convolution(horizontal="0 1 0", vertical="-1 2 -1",u=3,v=3) does the convolution ok.
It's the same for :
myclip.mt_convolution("0 1 0","-1 2 -1",u=3,v=3)
BTW my version is 2.0 a8
Manao
8th November 2005, 21:46
AVIL : thanks for the report, it's fixed :
Changed from alpha 8 to alpha 9 : * fixed : mt_lut, mt_lutxy : even faster loading
* fixed : mt_convolution : negative coefficients were offseted by 1
* fixed : mt_convolution : division by zero if the sum of the coefficients was 0.
puffpio
8th November 2005, 22:29
the link to a9 is broken..it looks like it's not on the server
Manao
9th November 2005, 05:23
Fixed
AVIL
9th November 2005, 23:57
@Manao
mt_lutxy and mt_lut (version 2.0a9) dont work :
mt_LUTxy(myclip,myclip,"x y - abs" , "128", "128",u=3,v=3)
gives a pale green clip
yv12LUTxy(myclip,myclip,"x y - abs" , "128", "128",u=3,v=3)
gives a black clip, as spected.
mt_lut(myclip,"x 25 < 255 0 ?" , "128", "128",u=3,v=3)
gives an uniform pale green clip also
yv12lut(myclip,"x 25 < 255 0 ?" , "128", "128",u=3,v=3)
gives a binary clip, as spected.
Manao
10th November 2005, 00:07
This time, it's not a bug. Arguments should always be named to avoid all confusion. In this case, you didn't notice that I added a fourth string, "expr", in addition to "yExpr", "uExpr" and "vExpr", whose purpose is to serve as default expression if one is missing. Order is expr, yexpr, uexpr, vexpr, so vexpr is missing, replaced by the first one, and yexpr is "128".
AVIL
10th November 2005, 07:06
@manao
Sorry.
Indeed, I must read the manual BEFORE use (not AFTER how I'm accustomed)
Didée
10th November 2005, 09:40
Just a note, if anyone is scratching it's head like I was ... the "equal" operator has been changed to "==" in MT 2.x , where it was "=" in MT 1.5.x ...
"x y = 255 0 ?" --> "x y == 255 0 ?"
It's fine that way, but isn't noted anywhere ... lut description refers to the old 1.5.x documentation.
Manao
10th November 2005, 09:53
Never use that operator anyway. Numbers are floats during the lut precomputation, and you should never do a =(=) b with floats. Rather use abs(a-b) < epislon instead.
But I'll update the documentation.
Didée
10th November 2005, 10:41
When checking the hyperbolic cosecant of a complex power against <value>, sure. /*earnest face*/ :D
For direct checking of pixel values, "=" has proven to be quite handy.
"x 128 = [this] [that] ?" (a)
is readable. When instead writing
"x 128 - abs 0.00001 < [this] [that] ?" (b)
then, while we're at it anyways, why not make it completely unreadable like
"x 128 - 128 x - * 1 2.0 / ^ 1 10000 / < [this] [that] ?" (c)
Somehow I prefer variant (a), dunno ... :)
Manao
10th November 2005, 10:51
Then, I could change =(=) operator to act like x y - abs epsilon <, what do you think of that ?. Because I persist in thinking that =, as such, on float, is a bad idea. If you need, I can even export the epislon parameter ( though 0.001 should be OK for most purposes ).
AVIL
16th November 2005, 21:24
@Manao
I've found that mt_convolution lacks of parameters "total", "automatic" and "saturate".
Although I can emulate "total" parameter with a posterior mt_lut step, I don't know how to mimic saturate.
Is possible to implement this parameters in mt_convolution or i must
use yv12convolution? (or ¿they are an easy method to emulate them?)
BTW, I agree with the idea of the epsilon for the == operator. I think also that checking pixel identity is a must for the LUT tools.
Thanks.
cwolf
20th November 2005, 17:09
It seems that the parameter "offy" is being disregarded in mt_lutxy. It is assuming "offx" as "offy" because no matter what I put in "offy" it is considering the value in "offx", so the "home" point is always a square. Could you confirm this? I'm using the 2.0a9 version dated nov 8th 21:41.
Cecilia
[edit]forgot to post the script:
mt_LUTxy (last,levels(0,1,255,255,255), yexpr="y", uexpr="y", vexpr="y",offx=64,offy=344,w=120,h=64)
levels is being used here for debugging purposes only.
Manao
20th November 2005, 17:19
cwolf : well spotted, fixed, I'll soon release a new version.
AVIL : sorry for having taken so long to answer : I'll add them ( automatic will be useless though ).
Manao
20th November 2005, 18:47
*bump*
Changed from alpha 9 to alpha 10 : * fixed : offY was always set to offX
* fixed : offset quirk
* fixed : mt_convolution was crashing with floats
* changed : luts' equal operator is now equivalent to abs(x-y) < 0.000001
* added : bool saturate(true) parameter to mt_convolution
* added : float total(1.0) parameter to mt_convolution
Didée
10th December 2005, 19:14
mt_convolution still has bugs. You can create weird output and access violations with
a = last
b = mt_convolution("1","1 4 6 4 1",U=2,V=2)
c = mt_convolution("1 4 6 4 1","1",U=2,V=2)
d = mt_convolution("1","1 4 6 4 1",U=2,V=2)
\ .mt_convolution("1 4 6 4 1","1",U=2,V=2)
e = stackvertical(stackhorizontal(a,b),stackhorizontal(c,d))
f = stackvertical(stackhorizontal(a,c),stackhorizontal(b,d))
#a
#b
#c
#d
#e
#f
return( last )
so it seems mt_convolution goes crazy when it gets input that was already processed by mt_convolution.
Interesting: on its own, the single-processed clips "b" and "c" are OK. In the stacked() output of "e", the "c" clip is distorted, too. And "f" just crashes with access violation.
Then, a question about shape-strings and expand & Co:
a) inflate/deflate
The readme of mt_masktools states: "compute a local average by taking into account only the neighbourgh whose value is higher than the pixel.
The html of v1.5.x states: Inflate will compute the mean of the surrounding pixels, and will replace the value of the pixel by it only if this mean is superior to the original value of the pixel.
This is definetly not the same operation. Has the behaviour changed, or is one of the two descriptions just not correct?
b) shape strings
I don't get the right grip to them. I.e. according to the readme of mt_masktools, the string "0 0 -1 0 1 0" is equivalent to "horizontal" for inpand/expand.
How does this work? the string has 6 numbers, but expand is working on 3x3 pixels ... so I'd rather expect a string with 9 numbers. Or is this similar to the "vector" format of mt_convolution, with both strings packed into one?
Then, radii bigger than 1 are supposed to work, yes? However when producing accordingly long strings, the respective filters do ~something~, but for me it's not predictable. In the same breath, the strings produced by the helpers mt_circle, mt_square etc. I just do not understand. Perhaps the string creation is buggy, perhaps the way the strings get interpreted from other filters is buggy. Perhaps I am buggy. ;)
Manao
10th December 2005, 20:35
Ok, well spotten bug, it's fixed. For inflate / deflate, I changed the behavior ( by mistake ). I can change it back, or change current inflate / deflate and add back the old one.
For the shape : you give a list of relative coordinates : 0 0 -1 0 1 0 means (0,0), (-1,0) and (1,0). Expand can now work on any kind of "kernel", so the 3x3 size doesn't matter anymore ( though the good old 3x3 kernel is speeded up by isse optimizations ).
So : http://manao4.free.fr/masktools-v2.0a11.zip
Changes : * fixed : mt_convolution's multiple instanciation bugEdit : I almost forgot, once again, thanks a lot for your previous feedback Didee.
Edit2 : i tested prefetching the lut tables, it doesn't help on my amd64
Manao
13th December 2005, 09:31
There's a bug when a mode Y,U,V < 1 is used and the resolution of the channel is only mod4 horizontally. It'll be fixed tonight. Thanks a lot Lefungus for pointing that out.
Didée
13th December 2005, 11:01
While you're at it, could you have a look at two things:
1) mt_merge :
It seems that in comparison to MaskedMerge, mt_merge handles the input clips swapped:
MaskedMerge(a,b,m) == mt_merge(b,a,m)
2) FitY2UV :
At times I love this handy little function ... but since it uses ReduceBy2() internally, it has two small issues:
- throws an error when the input width is MOD4, but not MOD8: "Resize: YV12 width must be a multiple of 4.".
It's not such a big deal ... if one is foreseeing to use FitY2UV, one can force MOD8 as well. Still, it would be more convenient if that would work, too.
- ReduceBy2() generally produces an offset that XYZresize() doesn't. If a (perhaps even multiple) reduce'd frame is upscaled to full resolution again, this might become a problem. It would be beneficial to call a standard resizer instead of Reduce (if possible).
BTW, thank you for the clarification on the shape strings. Didn't see the wood for the trees. ;)
Manao
13th December 2005, 11:11
You can script FitY2UV ( usually, speed doesn't matter when you use FitY2UV, does it ? or am I missing sth ? )
For mt_merge, reading the source code, it seems indeed it's swapped. But isn't it the correct order ? Because I kinda remind always having trouble with MaskedMerge's order.
Didée
13th December 2005, 11:43
Well, about how a mask should be interpreted, the world falls apart in two parts:
a) Mask is interpreted as "opacity"
b) Mask is interpreted as "amount"
Personally, I am always confused by the "opacity" interpretation, as it's used in Overlay(). I'm never sure to *what* the opacity refers - does it define opacity for the base image or for the image getting overlayed, or have I to imagine the mask lying between the two layers, where the opacity tells how much image will "diffuse" through the mask?
But then, where does a mask have "full opacity" again - at Y=0, or at Y=255?
Again personally, I find the "amount" interpretation much easier to understand:
- we have a base image
- we have an image we want to overlay
- the mask tells how much copying to do: 0=copy nothing, 255=copy everything. Period.
For example, the not-famous (alas) "photographic editor" Picture Window (http://www.dl-c.com/Temp/store/store_content_pw.html) does it this way:
http://img230.imageshack.us/img230/6712/pw2masking4hx.th.png (http://img230.imageshack.us/my.php?image=pw2masking4hx.png)
Of course, both points of view are perfectly valid. For my taste, the "amount" interpretation is much more intuitive to work with (read: requires less brainpower ;) ). If you prefer the other way round (the Photoshop way) more, we'll arrange with that way, too.
Manao
13th December 2005, 13:14
OK, now I know what i swapped : I do see the mask as an amount of the frame but I apply the mask to the first clip instead of the second :). So here's a quick poll : who's for d = s1 * m + s2 * (256-m) and who's for d = s1 * (256-m) + s2 * m. Tonight I do the change, so be quick :D
mg262
13th December 2005, 13:43
I'm for Didée's "amount" implemented as shown in the screenshot. I think that is d = s1 * (256-m) + s2 * m, yes?
Didée
13th December 2005, 14:19
Yeeeeeh, that's 2 vs. 1 :D
BTW, I updated the screenshot ... named application supports 2 masks at the same time, and this way it's a better reflection of the proposal. :o
Manao
13th December 2005, 20:57
OK, 2 vs 1, you win :
http://manao4.free.fr/masktools-v2.0a12.zip
Changelog from alpha 11 to alpha 12
* fixed : bug with some width ( mod4 ) for the non processing mode ( != 1 or 3 )
* changed : mt_merge order swapped for mask operation
Alain2
13th December 2005, 22:20
Does that mean we have to (for instance) swap accordingly mt_merge clips in limitedsharpenfaster ?
Manao
13th December 2005, 22:29
That means that the clips must be in the same order as in the LimitedSharpen with MaskedMerge. Sorry for the confusion, but I hadn't realized that I swapped the order when going from 1.5.8 to 2.0a
mg262
14th December 2005, 17:08
Manao -- Thank you for the update!
Alain2,
Socio modified LimitedSharpen to use this new version of MaskTools, but I think it was running into difficulties (with LMode = 3 only) precisely due to the changed argument order. So it should be the case that the script works correctly with this new version of MaskTools.
The modified-modified version I released (limitedsharpenfaster) uses Socio's code almost everywhere, so the same should apply. I won't have time to test all this for a while, but you can do it yourself... just call something like
Subtract(LimitedSharpen(...), limitedsharpenfaster(...))
levels(128-15, 1, 128+15, 16, 235) #magnify the difference
and scroll through the result. The two scripts should return exactly the same thing, so you should get a flat grey output.
Manao
14th December 2005, 17:20
Subtract(LimitedSharpen(...), limitedsharpenfaster(...))
levels(128-15, 1, 128+15, 16, 235) #magnify the difference You certainly wanted to write mt_lutxy(LimitedSharpen(...), limitedsharpenfaster(...), "x y - 255 * 128 +", y=3, u=3, v=3), didn't you ? :D
foxyshadis
14th December 2005, 17:23
I think the new version of mt_merge broke something.
x=avisource("some.avi")
y=x.trim(200,0)
mask=x.mt_binarize(threshold=20).FitY2UV
m1=maskedmerge(x,y,mask,u=3,v=3)
m2=mt_merge(y,x,mask,u=3,v=3)
return stackhorizontal(m1,m2,mask)
m1 always gives the results I expect, m2 gives what looks like a 50/50 merge when mask is all black. Returning to 2.0a11 (and swapping parameters) gives a matching output. Happens with color and luma-only processing.
Manao
14th December 2005, 20:48
Erm... I did swapped the two input clips. Just not the good ones :D. I swapped the mask with the second clip instead of the two first clips... I'm shameful ( though I did laugh when I saw what I did :) )
Anyway, here's the fixed version : http://manao4.free.fr/masktools-v2.0a13.zip
Changelog : * fixed : mt_merge order swapped for mask operation ( no comment... )
mg262
14th December 2005, 21:29
I don't think you should be embarrassed. Since the connection between argument order and argument usage is distributed across three locations in the code:
-- string passed into AVISynth
-- Create function for the relevant filter
-- filter constructor
fiddling with parameter order is IMO very fiddly and easy to slip on -- hopefully it will be easier in 3.0. But I drift OT...
Fizick
14th December 2005, 22:36
Manao,
I am not very understand what I ask, :)
but any chance to implement not 1-pixel inflate-deflate for more general morphological open-close operations?
Manao
15th December 2005, 00:49
Fizick : that is already possible for inpand / expand : do you want that for inflate / deflate as well, or were you thinking of inpand / expand in the first place ?
Didée
15th December 2005, 01:39
Hmh ... having shapes for in/deflate would be interesting to see, but how useful are they going to be? For mask dilation, wouldn't it simply need the operation of expand(), only that each candidate pixel's value is altered by f(distance) before checking, with f = linear, cosine, gauss, etc.? And the same way, by enabling radii < 1.0 and working supersampled internally, there is (edge)mask contraction/thinning.
Fizick
15th December 2005, 18:15
Manao,
thanks, i will try read the readme. I did not try use new version.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.