View Full Version : MaskTools 2.0a48
Pages :
1
2
3
4
5
6
7
8
9
10
[
11]
12
13
lansing
12th April 2012, 04:58
i have a noob question about mt_merge as in this line
mt_merge(clip1, clip2, mask, U=3,V=3)
does it read: merge U and V color plane of clip1 and clip2, according to the mask? So if the mask is mt_edge, it will then merge the edge area only?
Gavino
12th April 2012, 11:44
I'm wondering about "mt_LUTs", the documentation for this filter seems off from the actual behavior of the filter. So I ask here to be certain that I'm not the error... Is this correct?
mt_square(1)?
y | y | y
y | x | y
y | y | y
mt_diamond(1)?
| y |
y | x | y
| y |
If this is correct, then why two input clips?
Your diagrams are wrong - all entries should be 'y' as they define a neigbourhood in 'clip2'.
There is no 'x' there, as x corresponds to the pixel from 'clip1'.
The examples in the docs all use the same clip for both clip1 and clip2, but in the general case these need not be the same.
mt_merge(clip1, clip2, mask, U=3,V=3)
does it read: merge U and V color plane of clip1 and clip2, according to the mask? So if the mask is mt_edge, it will then merge the edge area only?
Yes (and it will also merge the Y planes in the same way).
Didée
12th April 2012, 12:05
@lansing
Yes, exactly that. However: with that syntax, the edge-mask has to contain "the edges" in its U+V planes (i.e. mt_edge() must have also been run with U=3,V=3). And moreover, this can turn out problematic - local contrast usually is rather low in the UV planes, and therefore edge masking usually gives a weak mask on U+V.
Often it is better to use the luma edge mask for the UV planes, that's what the "luma=true" switch in mt_merge is for. In the same breath it might be benefitial to expand the mask, to compensate for the lower chroma resolution.
mt_merge(clip1, clip2, emask.mt_expand(), luma=true, Y=2,U=3,V=3)
(It's not necessary to do this luma->chroma plane linking ... but quite often this is "what the user in fact is trying to do").
@Granit
You are mixing up two different things. The LUTs with two input clips are using pixel values from both input clips to compute new output pixels. The morphological operators mt_diamond/square/etc are defining the pixel neighborhood on which the "mode" operation should be computed on.
Hmh, clear as mud.:D - Example:
mt_lutf(c1,c2,mode="median",pixels=mt_diamond(2),expr="x y * 0.5 ^",Y=3,U=2,V=2)
Does the following:
On clip c1, for each pixel "X" compute the median of the following neighborhood n:
o o o o o o o
o o o n o o o
o o n n n o o
o n n X n n o
o o n n n o o
o o o n o o o
o o o o o o o
Now the median has been computed for each pixel of c1.
Next in this example is to compute the geometric mean {sqrt(x*y), that's what I've written for "expr"} for each c1<>c2 pixel pair, where the "x" in the lut is the median from c1, and the "y" in the lut is the pixel value from c2.
Gavino
12th April 2012, 13:03
mt_luts(c1,c2,mode="median",pixels=mt_diamond(2),expr="x y * 0.5 ^",Y=3,U=2,V=2)
Does the following:
On clip c1, for each pixel "X" compute the median of the following neighborhood n:
o o o o o o o
o o o n o o o
o o n n n o o
o n n X n n o
o o n n n o o
o o o n o o o
o o o o o o o
Now the median has been computed for each pixel of c1.
Next in this example is to compute the geometric mean {sqrt(x*y), that's what I've written for "expr"} for each c1<>c2 pixel pair, where the "x" in the lut is the median from c1, and the "y" in the lut is the pixel value from c2.
No, what you have described is mt_lutf.
For mt_luts, it evaluates the expression with x as the pixel in clip1 and y as each pixel in the corresponding neigbourhood in clip2, giving a set of results. The median (or the specified function) is then applied to that set to give the result value for that pixel.
Didée
12th April 2012, 13:23
Oh, you fell for my unreadable handwriting - my "f" and "s" are almost indistinguishable.
Blame on me, blame on me, blame on me ... :o :o :o
lansing
12th April 2012, 17:16
thanks Gavino and Didée. So by merging, clip1 and clip2 will each contribute 50% to the mask? What if I wanted to replace the edge of clip1 with clip2? I do mt_merge(...chroma="copy second")?
Gavino
12th April 2012, 17:57
So by merging, clip1 and clip2 will each contribute 50% to the mask? What if I wanted to replace the edge of clip1 with clip2? I do mt_merge(...chroma="copy second")?
Each output pixel of mt_merge is produced by mixing the corresponding pixels of clip1 and clip2 in the proportion determined by the corresponding pixel of the mask. As the documentation says, "The bigger the mask value, the more the second clip will be taken into account ( the actual formula is y = ((256 - m) * x1 + m * x2 + 128) / 256 )".
So the idea is to first create a mask which represents the way you want the merging to take place. If you want to replace the edges of clip1, then you would use clip1.mt_edge(...) as the mask.
mt_merge(clip1, clip2, clip1.mt_edge(...), ...)
chroma="copy second" is a separate issue and would take the chroma completely from clip2 regardless of the mask, probably not what you want.
Granit
12th April 2012, 20:13
Thank you Gavino and Didée for clearification. The reason I ask is because I'm trying to learn how to operate avisynth properly, currently I'm on the first knob of a steep learning curve...
I usally load single frames or a single set of frames to learn what I'm doing.
The operation I had in mind would be similar to mt_LUTs, but with only one input clip. Where x is center and y is matris pixel, so that mode="x y 32 + > x y 32 - < | med x ? ". Is such and operation possible with masktools (probably) and how would be a good way of doing that?
@Lansing
Do an mt_Edge(). Study the output. The "whitest" pixels are the ones that are "transparent". With merge, input, filling_clip, mask. filling clip will be put "on top" of input, but only where the mask is "transparent". The the mask is to 0 (black), the more the resulting clip will be a mix of input and filling_clip.
Gavino
12th April 2012, 23:25
The operation I had in mind would be similar to mt_LUTs, but with only one input clip. Where x is center and y is matris pixel, so that mode="x y 32 + > x y 32 - < | med x ? ".
Can you explain in words what this operation actually means?
For a given input pixel (x), is the condition evaluated for each neigbourhood pixel (y)? And then what happens to derive the single output pixel?
Granit
13th April 2012, 01:46
@Gavino: I Apologize if I'm not very clear or articulate, english isn't my native language.
What I mean is; If all of the matris pixels were mapped to the y (or any other) variable, and the center pixel to the x (or any other) variable then it would look as such (in an 3 by 3 matris):
Y Y Y
Y X Y
Y Y Y
Now with such a filter, being very generic, many different computations could be possible. e.g in my above post or, perhaps something as such: expr=”x avg 1.25 * > med ?”. In this example it would look for single pixels that are >25% above its eight surrounding neighbors and mediate the ones it finds. With a matris of say 1 by 20 pixels, it could be used for looking for aliases or perhaps remaining scan-lines, or or or... I, in my own humble opinion, think that such a filter is very possible and would be very useful. I also think, perhaps mistakenly, that it, or something similar, could be done with existing filters / framework.
Thank you for invested patience and, perhaps, sanity.
lansing
13th April 2012, 07:42
Each output pixel of mt_merge is produced by mixing the corresponding pixels of clip1 and clip2 in the proportion determined by the corresponding pixel of the mask. As the documentation says, "The bigger the mask value, the more the second clip will be taken into account ( the actual formula is y = ((256 - m) * x1 + m * x2 + 128) / 256 )".
So the idea is to first create a mask which represents the way you want the merging to take place. If you want to replace the edges of clip1, then you would use clip1.mt_edge(...) as the mask.
mt_merge(clip1, clip2, clip1.mt_edge(...), ...)
chroma="copy second" is a separate issue and would take the chroma completely from clip2 regardless of the mask, probably not what you want.
thank you for the explanation, and Granit.
i'm currently trying to finalize my attempt of stabilizing flickering line in anime, with mt_merge+mt_edge here (http://forum.doom9.org/showthread.php?p=1569657#post1569657). Things seem to work out so far until scene with night sky and stars. The problem is that mt_edge also considered the stars as edges, so when my script is to clean the edge mask, it will also clean the stars, and most of the time just wiped them out completely.
What I'm thinking is to create a mask of the star, and then have it subtracted from the edge mask, resulting in a edge mask without the star. Is this idea possible?
I've checked out LaTo's MCTD, he has an option to protect the star from denoised, and it read somewhat like
cutoff = 64 #Luma cutoff (process only brighter areas than this value) [0=all,1...255]
threshold = 16 #Luma threshold (minimal change needed to be filtered, the higher = the lesser areas are filtered) [0...127]
maxdiff = 4 #Maximum change allowed between source and result (the lesser, the brighter) [0=source,1...255]
i = defined(source) ? source : denoised
smP = denoised
chr21 = chroma?2:1
### PROTECTING
rg17 = smP.removegrain(17,-1)
iOB = i.mt_lut("x "+string(cutoff)+" >= x 0 ?",U=1,V=1)
mB = mt_makediff(iOB,rg17,U=1,V=1).mt_binarize(128+threshold,upper=false,U=1,V=1).removegrain(5,-1)
lB = mt_lutxy(smP,i,"x y - abs "+string(maxdiff)+" <= x x y - 0 < y "+string(maxdiff)+" - x ? ?",U=1,V=1)
smB = mt_merge(smP,lB,mB,U=chr21,V=chr21)
i have difficulty understanding what the script does and how to create a star mask from it.
Gavino
13th April 2012, 10:34
Oh, you fell for my unreadable handwriting - my "f" and "s" are almost indistinguishable.
Looking at this again, mt_lutf doesn't work that way either.
It doesn't have a pixels parameter, and the median (or whatever) operation is applied to the entire frame, not a neighbourhood of the relevant pixel.
Gavino
13th April 2012, 10:36
Now with such a filter, being very generic, many different computations could be possible. e.g in my above post or, perhaps something as such: expr=”x avg 1.25 * > med ?”. In this example it would look for single pixels that are >25% above its eight surrounding neighbors and mediate the ones it finds.
I don't think that can be done currently.
mt_luts goes part of the way, but the median or (whatever) operation is always applied to a fixed number of values (the size of the specified neighbourhood) - there is no way to conditionally select a subset of that neighbourhood and take the median of that subset.
cretindesalpes
13th April 2012, 12:16
I don't think that can be done currently.
mt_luts goes part of the way, but the median or (whatever) operation is always applied to a fixed number of values (the size of the specified neighbourhood) - there is no way to conditionally select a subset of that neighbourhood and take the median of that subset.
Arbitrary number of values can be achieved using BucketMedian (http://csbarn.blogspot.fr/2012/04/bucketmedian-2.html) by setting the rejected values to 0 (or 255) and setting min to 1 (or max to 254). However the clip would need to be cooked to present distinct groups of 3x3 pixels before processing.
w = Width ()
h = Height ()
# 3x3 pixel blocks
a = group3lines ().TurnRight ().group3lines ().TurnLeft ()
# Average of the 8 surrounding pixels
b = RemoveGrain (19)
b = b.PointResize (w*3, h*3)
# Rejected pixels are set to 0
x = mt_lutxy (a, b, "x y 1.25 * > x 0 ?", u=3, v=3)
x = x.BucketMedian (radius=1, min=1)
x = x.PointResize (w, h, 1, 1)
mt_lutxy (x, last, "x 0 == y x ?", u=3, v=3)
Function group3lines (clip c)
{
c
w = Width ()
h = Height ()
c0 = c.PointResize (w, h, 0, 0)
c1 = c.PointResize (w, h, 0, 1)
c2 = c.PointResize (w, h, 0, 2)
c02 = Interleave (c0, c2).AssumeFieldBased ().AssumeTFF ().Weave ()
c12 = Interleave (c1, c2).AssumeFieldBased ().AssumeTFF ().Weave ()
c0122 = Interleave (c02, c12).AssumeFieldBased ().AssumeTFF ().Weave ()
PointResize (c0122, w, h*3)
}
I don't know if it's exactly what you wanted to do.
Granit
13th April 2012, 19:39
I don't think that can be done currently.
mt_luts goes part of the way, but the median or (whatever) operation is always applied to a fixed number of values (the size of the specified neighbourhood) - there is no way to conditionally select a subset of that neighbourhood and take the median of that subset.
That's a shame. I guess it was just my wishful thinking then, atleast now I know I'm the error...
Result of cretindesalpes fine code can be seen (after download) here
http://www.streamfile.com/myid/FlYaXqchViIW
The code suggested in my last post was just an example, I wished for ”pixels=” and ”expr=” because I thought such a filter would be very handy sometimes.
Thank you all for your help.
cheeseboy
20th June 2012, 20:17
I'm trying to port Masktools2 to avxsynth (linux) but it kinda took a shit on me. I got it to build and load but it doesn't seem to work correctly at all. Heres a video of the fail http://dl.dropbox.com/u/26289275/masktoolsfail.ogv . And heres my git with all the changes https://github.com/fundies/MaskTools2-linux .
sl1pkn07
23rd June 2012, 11:56
wo! thankius!!
EDIT: masktools/common/common.cpp:3:21: fatal error: windows.h: No such file or directory
cheeseboy
24th June 2012, 13:30
that file shouldn't even be built... its explicitly commented out in the makefile.
sl1pkn07
24th June 2012, 13:48
doh. my fail. run genmake.sh before make. sorry.
for the info. to build need install boost
greetings and good work
EDIT:
i'm making package for my distro (archlinux). the namcap (package tester) say:
avxsynth-plugin-masktools2 W: ELF file ('usr/lib/avxsynth/libmasktools.so') has executable stack.
sl1pkn07@sL1pKn07 masktools-build $ readelf -l libmasktools.so
Elf file type is DYN (Shared object file)
Entry point 0x61300
There are 7 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000142582 0x0000000000142582 R E 200000
LOAD 0x0000000000142f50 0x0000000000342f50 0x0000000000342f50
0x0000000000004dd8 0x0000000000005df8 RW 200000
DYNAMIC 0x0000000000144d88 0x0000000000344d88 0x0000000000344d88
0x00000000000001f0 0x00000000000001f0 RW 8
NOTE 0x00000000000001c8 0x00000000000001c8 0x00000000000001c8
0x0000000000000024 0x0000000000000024 R 4
GNU_EH_FRAME 0x000000000012dff0 0x000000000012dff0 0x000000000012dff0
0x00000000000022cc 0x00000000000022cc R 4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RWE 8
GNU_RELRO 0x0000000000142f50 0x0000000000342f50 0x0000000000342f50
0x00000000000030b0 0x00000000000030b0 R 1
Section to Segment mapping:
Segment Sections...
00 .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .rdata .eh_frame_hdr .eh_frame .gcc_except_table
01 .init_array .fini_array .jcr .data.rel.ro .dynamic .got .got.plt .data .bss
02 .dynamic
03 .note.gnu.build-id
04 .eh_frame_hdr
05
06 .init_array .fini_array .jcr .data.rel.ro .dynamic .got
sl1pkn07@sL1pKn07 masktools-build $ execstack libmasktools.so
X libmasktools.so
fixed warning with execstack -c libmasktools.so
Chikuzen
6th September 2012, 13:11
today, I tried to test whether masktools would work by VapourSynth (http://forum.doom9.org/showthread.php?t=165792).
>>> import vapoursynth as vs
>>> core = vs.Core()
>>> core.avs.LoadPlugin("mt_masktools-26.dll")
>>> core.list_functions()
then, there was an unfamiliar function on the displayed list.
mt_gradient(c1:clip;c2:clip;distorsion:data:opt;size_x:int:opt;size_y:int:opt;min:int:opt;max:int:opt;precision:int:opt;
Y:int:opt;U:int:opt;V:int:opt;chroma:data:opt;offX:int:opt;offY:int:opt;w:int:opt;h:int:opt;
mmx:int:opt;isse:int:opt;sse2:int:opt;sse3:int:opt;d3now:int:opt;d3now2:int:opt;ssse3:int:opt;sse4:int:opt;)
What's mt_gradient() ?
StainlessS
6th September 2012, 15:59
only references to 'gradient' I could find
wrapper.cpp
extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env)
{
...
...
...
Avisynth2x::Filter<Gradient::Filter>::create( env );
...
...
...
return("MaskTools: a set of tools to work with masks");
}
gradient\filter.h
class Filter : public MaskTools::Filter<ChildFilter>
{
ProcessorList<Processor> processors;
int nX[3];
int nY[3];
int nMinimum;
int nMaximum;
int nPrecision;
protected:
virtual void process(int n, const Plane<Byte> &dst, int nPlane)
{
UNUSED(n);
processors.best_processor( constraints[nPlane] )( dst, dst.pitch(), frames[0].plane(nPlane), frames[0].plane(nPlane).pitch(), \
frames[1].plane(nPlane), frames[1].plane(nPlane).pitch(), dst.width(), dst.height(), nX[nPlane], nY[nPlane], nMinimum, nMaximum, \
nPrecision );
}
public:
Filter(const Parameters ¶meters) : MaskTools::Filter<ChildFilter>( parameters )
{
/* add the processors */
if ( parameters["distorsion"].toString() == "sad" )
{
processors.push_back(Filtering::Processor<Processor>(sad_c, Constraint(CPU_NONE, 1, 1, 1, 1), 0));
nMinimum = parameters["min"].is_defined() ? parameters["min"].toInt() : 0;
nMaximum = parameters["max"].is_defined() ? parameters["max"].toInt() : 65535;
}
else
{
error = "unknown distorsion";
return;
}
nX[0] = parameters["size_x"].is_defined() ? clip<int, int>(parameters["size_x"].toInt(), 0, nCoreWidth - 1) : nCoreWidth / 2;
nY[0] = parameters["size_y"].is_defined() ? clip<int, int>(parameters["size_y"].toInt(), 0, nCoreHeight - 1) : nCoreHeight / 2;
nPrecision = parameters["precision"].toInt();
for ( int i = 1; i < plane_counts[C]; i++ )
{
nX[i] = nX[0] / width_ratios[i][C];
nY[i] = nY[0] / height_ratios[i][C];
}
}
InputConfiguration &input_configuration() const { return TwoFrame(); }
static Signature filter_signature()
{
Signature signature = "mt_gradient";
signature.add(Parameter(TYPE_CLIP, ""));
signature.add(Parameter(TYPE_CLIP, ""));
signature.add(Parameter(String("sad"), "distorsion"));
signature.add(Parameter(0, "size_x"));
signature.add(Parameter(0, "size_y"));
signature.add(Parameter(0, "min"));
signature.add(Parameter(65535, "max"));
signature.add(Parameter(1, "precision"));
return add_defaults( signature );
}
};
gradient\filters.cpp
#include "filter.h"
using namespace Filtering;
typedef int (Distorsion)(const Byte *pSrc, ptrdiff_t nSrcPitch, const Byte *pRef, ptrdiff_t nRefPitch, int nPrecision);
template<int nBlockSizeX, int nBlockSizeY> int sad(const Byte *pSrc, ptrdiff_t nSrcPitch, const Byte *pRef, ptrdiff_t nRefPitch, \
int nPrecision)
{
int nSad = 0;
for ( int y = 0; y < nBlockSizeY; y++, pSrc += nSrcPitch * nPrecision, pRef += nRefPitch * nPrecision )
for ( int x = 0; x < nBlockSizeX; x++ )
nSad += abs<int>( pSrc[x * nPrecision] - pRef[x * nPrecision] );
return nSad;
}
template<Distorsion distorsion, int nBlockSizeX, int nBlockSizeY> void generic_c(Byte *pDst, ptrdiff_t nDstPitch, \
const Byte *pSrc, ptrdiff_t nSrcPitch, const Byte *pRef, ptrdiff_t nRefPitch, int nWidth, int nHeight, int nX, \
int nY, int nMinimum, int nMaximum, int nPrecision)
{
int x, y;
pSrc += nX + nY * nSrcPitch;
for ( y = 0; y < nHeight - nBlockSizeY * nPrecision + nPrecision; y++, pRef += nRefPitch, pDst += nDstPitch )
{
for ( x = 0; x < nWidth - nBlockSizeX * nPrecision + nPrecision; x++ )
pDst[x] = clip<Byte, int>( (distorsion( pSrc, nSrcPitch, &pRef[x], nRefPitch, nPrecision ) - nMinimum) \
* 255 / (nMaximum - nMinimum) );
for ( ; x < nWidth; x++ )
pDst[x] = pDst[nWidth - nBlockSizeX * nPrecision + nPrecision - 1];
}
for ( y = 0; y < nBlockSizeY * nPrecision - nPrecision; y++ )
memcpy( &pDst[y * nDstPitch], pDst - nDstPitch, nWidth );
}
namespace Filtering { namespace MaskTools { namespace Filters { namespace Gradient {
Processor *sad_c = &generic_c<sad<16, 16>, 16, 16>;
} } } }
all I could find
kurish
10th November 2012, 01:58
Is it possible to simply expand a mask by an arbitrary number of pixels?
e.g., the first mask below is turned into the second by expanding outwards 15 pixels. This was done manually in an image editing program, however, and I'd like MaskTools to do it automatically:
http://i.imgur.com/tAi1S.jpg http://i.imgur.com/RCg8q.jpg
Apologies for such a super-noob question; I have read up on the subject but can't find a solution. Thank you.
Edit: looks like it's as easy as multiple calls of mt_expand(u=2,v=2). The u/v=2 thing really threw me off...
wOxxOm
12th November 2012, 19:49
kurish, mt_expand_multi(sw=15,sh=15)
leeperry
19th November 2012, 14:36
Hi Manao, a while ago you told me that you would consider adding 10/16bit capabilities to mvtools.....any news on that matter by any chance please?
There are working P016 hacks for several other major Avisytnh plugins, but every script based on yours(SVP frame interpolation or many/most of Didée's scripts) is still stuck in YV12 land....which defeats the purpose of using madVR to begin with, it's like processing audio in 16int instead of 64fp :(
:thanks:
Keiyakusha
19th November 2012, 22:08
There is no point it what you ask in every thread. Avisynth doesn't work/support or whatever with P016 with hacks or without. It won't output P016. You need vapoyrsynth for that.
leeperry
19th November 2012, 22:22
Well, SmoothLevels can output 16bit using hacks and Manao told me like a year ago that he'd think about it. Once more and more plugins will support 16bit, it will only be a matter of having ffdshow modified in order to recognize those hacks.
There are far more chances of seeing this being successfull than someone adding VS support in ffdshow and all those plugin coders rewriting them for VS you know.
Keiyakusha
19th November 2012, 22:24
if it outputs 16bit it doesn't means it outputs P010 (or actually its P016 for 16bit). P016 is just one out of many 10bit colorspaces. And what avisynth outputs, even if its 10-16bit is hacked YV12. You need to hack every host software as well if you want it to accept it. There won't be P010 support in avisynth ever. I don't see it happening judging by how it is developed and that we have vapoursynth now anyway.
leeperry
19th November 2012, 22:29
Anything more precise than 8bit YV12 that wouldn't require drastic changes/rewriting will make my day...it will only be a matter of processing a lossless conversion to a format that mVR could understand inside ffdshow. Don' be so negative ;)
Keiyakusha
19th November 2012, 22:36
But you want to output it undithered to something like madvr right? Not possible if you won't hack madvr. And if you want only processing and output dithered yv12 is ok, then I believe you can process 16bit with mvtools as long as it uses stack16format. There was sctipts that automate the process for denoising, But not sure how we would go with frame doubling (and you seem to want that)...
But without proper high bitdepth support, all of this is probably too slow for realtime processing anyway. Especially in avisynth.
TheFluff
19th November 2012, 22:49
Anything more precise than 8bit YV12 that wouldn't require drastic changes/rewriting will make my day...it will only be a matter of processing a lossless conversion to a format that mVR could understand inside ffdshow. Don' be so negative ;)
In the last two years the Avisynth 2.6 alpha (which you are putting your hopes in) has progressed very little. It has one active developer (the tireless IanB), the interface is still not finished and it will not have support for more than 8 bits per sample in any colorspace even when it eventually gets a finished interface.
In the last two weeks, VapourSynth has gotten a pile of new plugins, it has a stable interface and a whole crowd of active developers and testers.
Extending a) masktools, b) the ffdshow avisynth interface, and c) the avisynth core itself so that it can process and output high bitdepth video is most definitely not something that "wouldn't require drastic changes". At the very least, you're talking about rewriting the processing core of a huge filter collection (the codebase of which is an incredible mess) and mucking around to quite a significant degree in ffdshow (a nasty piece of work to maintain even under optimal circumstances), and that's if you disregard the Avisynth API and output in one of the "hack" modes (which means you'll manually have to tell ffdshow what the input is). To be brutally honest; while all of these changes are theoretically possible, they will never actually happen. People have been asking for high bitdepth support in various places for years, and pretty much the only thing that's happened is dithertools, whose author is now working on vapoursynth stuff.
leeperry
20th November 2012, 08:52
alright, thanks for the explanation! so my only golden ticket will be to wait for PS script in mVR(processed in 32fp) and then wait for N-1 frames access so someone can write a frames interpolation script then =/
8bit video processing is really caveman technology..
martin53
20th November 2012, 21:48
Manao,
I'd like to suggest additional operators for RGBLUT/VY12LUT/YV12LUTxy.
( I am working with v1.5.8 - please comment if I should switch to mt_vxyz? )
min, binary operator, returns minimum of top 2 operands on stack
max, binary operator, returns maximum of top 2 operands on stack
dup, unary operator, duplicates top operand
swap, binary operator, swaps top 2 operands on stack
Didée
20th November 2012, 22:22
Seven years of MaskTools v2, and you're still working with v1? Is that serious, or are you trying to pull legs?
min and max are implemented in MaskTools v2. For dup and swap, I don't see any need?
@leeperry
There are a few minor problems. E.g. with mt_lutxy, being "the barebone" of custom scripting - take two clips, and compute whatever you need to compute. In 8bit land, one LUT table takes 64kB RAM. In the paradise of 16bit land, one LUT table takes 4096 MB RAM. Yes, that's 4 GB. That's obviously nonsense, you can't work with tables that big. Well, compute it at runtime then. Ooops, now the darn crap is 100 times slower than before. Hmm-hmm.
martin53
20th November 2012, 22:50
Seven years of MaskTools v2, and you're still working with v1? Is that serious, or are you trying to pull legs?
Yes, I am working with v1. I feel that I already spend much time in finding plugin updates. To be honest, I upgraded from v1.4.16 to v1.5.8 yesterday. On Manao's website, I saw e.g. masktools-v2.0a48.zip from December 2010 - but there are hundreds of files there, and how can I judge their matureness...?
As for 'dup': With min/max and the ? operator, it may be unneccessary. Without the min/max operators, I wondered how i can check if x-128 is positive and then take x-128, or else take 0: "x 128 - 0 < 0 x 128 - ?" But I admit that because of the order of operands for '?', 'dup' would not help. I would need the dup'ed operand on top of the comparison and the other operand, so more stack manipulation operators would be needed, and although it is cumbersome, maybe redundant entry is best. Or storage variables, please see the xyremap thread.
leeperry
21st November 2012, 00:38
In 8bit land, one LUT table takes 64kB RAM. In the paradise of 16bit land, one LUT table takes 4096 MB RAM.
Hah, thanks for the input! Make it 10 or 12bit then? So many successive 8bit passes can't do much good to the PQ IMHO, but life is about compromises and 10/12bit will already be an improvement w/o too much extra load maybe?
Mug Funky
21st November 2012, 04:56
the big LUT problem is interesting, as float 3d luts are routine in colour grading land. is this the difference that GPU computing makes?
most LUT formats used in grading (and increasingly the rest of the post workflow) are computed from a 16x16x16 "colour cube" that is input to the program. presumably they use bicubic interpolation or some such.
operating on 2 or 3 input clips would certainly complicate things though.
Chikuzen
21st November 2012, 06:19
In 8bit land, one LUT table takes 64kB RAM. In the paradise of 16bit land, one LUT table takes 4096 MB RAM. Yes, that's 4 GB.
In 16bit land, each value of the table needs 2bytes.
Thus, 2 * 65536 *65536 = 8GB :p
martin53
24th November 2012, 14:21
Seven years of MaskTools v2, and you're still working with v1?
Didée,
first I was a bit annoyed 'cause I never had come across a clear statement that v2 is the version designed for public - it is alpha and so on - my fault for sure.
The functions inside are great! And thanks for the hint about mt_lutspa!
bennynihon
19th March 2013, 19:17
Using the SET's latest Avisynth 2.6 MT and Masktools 2.0a48, I'm having an issue with frames being processed out of order when I enable MT via SetMTMode. In my output video (encoded by x264), I'll occasionally see a few interchanged frames which is noticeable as jumpiness in the output clip. When I comment out the SetMTMode lines, the issue disappears.
My clip is something as simple as this:
# Video Source
SetMemoryMax(1024)
SetMTMode(3)
FFVideoSource("e:\mymovie.mkv")
SetMTMode(2)
# Crop to 1920x800 (2.40:1 AR)
vSrc=Crop(0,140,0,-140)
# Degrain
bs = 16
super = vSrc.MSuper(pel=2, sharp=1)
bvec2 = MAnalyse(super, isb = true, delta = 2, blksize=bs, overlap=bs/2)
bvec1 = MAnalyse(super, isb = true, delta = 1, blksize=bs, overlap=bs/2)
fvec1 = MAnalyse(super, isb = false, delta = 1, blksize=bs, overlap=bs/2)
fvec2 = MAnalyse(super, isb = false, delta = 2, blksize=bs, overlap=bs/2)
vSrc.MDegrain2(super,bvec1,fvec1,bvec2,fvec2)
Overdrive80
20th March 2013, 01:04
Try with this (http://forum.doom9.org/showthread.php?p=1619023#post1619023). Thanks to -Vit- and 06_taro
bennynihon
20th March 2013, 21:52
Try with this (http://forum.doom9.org/showthread.php?p=1619023#post1619023). Thanks to -Vit- and 06_taro
Thank you! I'll give this a try.
~ VEGETA ~
20th July 2013, 20:47
how can I apply some filters only on dark areas? and the opposite too?
and, applying them on edges too...
thanks
martin53
23rd July 2013, 19:27
I am insecure if I misunderstand the manual or there is a bug in mt_luts() in V2.0a48 (as of dec. 31, 2010).
The manual says "x" is taken from clip1, "y" is taken from the "pixels" environment of clip2.
◾It computes the mode operation on the result of the function defined by expr, where x is the pixel from clip1, and y a pixel from the neighbourhood in clip2, defined by pixels.
Now if I define a "pixels" environment of just 1 pixel, I can see the direct expression result with e.g. the mode "avg". The most simple expression expr="x" should reflect clip1, right?
But in fact it does reflect clip2 instead.
mt_luts(blankclip(color_yuv=$400000, pixel_type="yv12"), colorbars(pixel_type="yv12"), mode="avg", pixels="0 0", expr="x", chroma="128")
foxyshadis
23rd July 2013, 23:52
how can I apply some filters only on dark areas? and the opposite too?
and, applying them on edges too...
thanks
Create a new named clip that is the original plus a filter. Then combine them with mt_merge and either mt_binarize to work on specific ranges of light, or mt_edge to work on edges. There are tons of scripts out there that do both, just look around this forum a bit.
TurboPascal7
24th July 2013, 03:06
I am insecure if I misunderstand the manual or there is a bug in mt_luts() in V2.0a48 (as of dec. 31, 2010).
The manual says "x" is taken from clip1, "y" is taken from the "pixels" environment of clip2.
Now if I define a "pixels" environment of just 1 pixel, I can see the direct expression result with e.g. the mode "avg". The most simple expression expr="x" should reflect clip1, right?
But in fact it does reflect clip2 instead.
mt_luts(blankclip(color_yuv=$400000, pixel_type="yv12"), colorbars(pixel_type="yv12"), mode="avg", pixels="0 0", expr="x", chroma="128")
Yes, this is a bug. mt_luts uses the value of the second clip as x instead of the first one. So whatever you pass as clip1 won't change the output.
Since people usually provide the same clip as both clip1 and clip2, no one ever noticed.
~ VEGETA ~
8th August 2013, 13:13
Create a new named clip that is the original plus a filter. Then combine them with mt_merge and either mt_binarize to work on specific ranges of light, or mt_edge to work on edges. There are tons of scripts out there that do both, just look around this forum a bit.
Thank you, but can you give me a quick example of both?
using a filter on edges and using a filter (say deband) on the dark areas only.
thanks in advance.
foxyshadis
10th August 2013, 00:22
Edges:
original = last
filtered = SomeFilter()
mask = mt_edge()
mt_merge(original,filtered,mask)
See the docs for masktools v2 if you want to refine the edgemask. You can use mt_merge(original,filtered,mask,luma=true) if you want to include the chroma channels in the filtering.
Dark areas:
original = last
filtered = SomeFilter()
mask = blur(1.4).mt_binarize(64)
mt_merge(original,filtered,mask)
Play with the threshold value. The "blur" is to make sure it applies even when there's a bit of noise on transitions, but even that won't be perfect. Might want to blur the results, so the threshold isn't so hard, or use levels instead for a somewhat smoother transition:
mask = Invert().Levels(128,1,191,0,255,coring=true)
Because it's inverted, this means process everything fully up to 64 (191=255-64), scaled from full to nothing 64 to 128, and nothing beyond that.
~ VEGETA ~
10th August 2013, 04:49
thanks for the reply.
See the docs for masktools v2 if you want to refine the edgemask. You can use mt_merge(original,filtered,mask,luma=true) if you want to include the chroma channels in the filtering.
luma=true is for chroma?
mt_merge(original,filtered,mask)
does the order matter and how?
mask = blur(1.4).mt_binarize(64)
I didn't understand the meaning of blur, but is 64 the threshold here? what does it really mean (bright, dark,..)?
this is important to understand (how to make thresholds).
mask = Invert().Levels(128,1,191,0,255,coring=true)
Because it's inverted, this means process everything fully up to 64 (191=255-64), scaled from full to nothing 64 to 128, and nothing beyond that.
hmm this is what I didn't understand the most.
___
so if I wanna filter the dark areas of some clip with f3kdb() and filter the really bright ones with say Deen (just an example)... and filter the edges with something else like an anti-aliasing filter. what is the full script with explanation?
thanks in advance.
Gavino
8th February 2014, 12:07
mt_polish parses nested conditionals incorrectly
For example,
mt_polish("x > 128 ? 255 : x > 64 ? 128 : 0")
produces
x 128 > 255 x 64 > ? 128 0 ?
instead of
x 128 > 255 x 64 > 128 0 ? ?
It can be worked round by putting the inner conditional in parentheses
mt_polish("x > 128 ? 255 : (x > 64 ? 128 : 0)")
but this should not be necessary.
Test script:
BlankClip(pixel_type="YV12")
Subtitle(mt_polish("x > 128 ? 255 : x > 64 ? 128 : 0"))
Subtitle(mt_polish("x > 128 ? 255 : (x > 64 ? 128 : 0)"), y=30)
Motenai Yoda
1st December 2014, 14:58
there is a little bug into mt_motion about tht/sc_value?
actually on scenechange whenever it should return a blank mask it return a plain mask at tht value.
meanwhile sc_value has no effect at all.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.