Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 25th March 2011, 14:47   #1  |  Link
Dogway
Registered User
 
Join Date: Nov 2009
Posts: 1,041
"Screen" algo in mt_lutxy

I borrowed the polish syntax from another function, but couldnt make the screen blend mode to perform correctly. It is most noticeable when black over black, where luma should be 16 is 31. Im using the next code:

Code:
mt_lutxy(a,b,"256 256 x - 256 y - * 256 / - " ,Y=3, U=2, V=2)
I also found in another web the infix syntax, I tried using it like so:
Code:
mt_lutxy(a,b,mt_infix("255 - (255-U)*(255-L)/255 ***"),Y=3, U=2, V=2)
but everything renders black.
Dogway is offline   Reply With Quote
Old 25th March 2011, 15:31   #2  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,406
Your formula assumes PC levels (0-255) rather than the normal 'TV' levels (16-235). Although the formula could be rewritten, the simplest solution is to use ColorYUV(levels="TV->PC") on both input clips before calling mt_lutxy, and ColorYUV(levels="PC->TV") after. But I think all your 256's probably should be 255's.

I've never heard of mt_infix - do you mean mt_polish?
The call could be written as:
Code:
mt_lutxy(a,b,mt_polish("255 - (255-x)*(255-y)/255"),Y=3, U=2, V=2)
__________________
GScript and GRunT - complex Avisynth scripting made easier

Last edited by Gavino; 25th March 2011 at 15:34.
Gavino is offline   Reply With Quote
Old 25th March 2011, 15:34   #3  |  Link
Didée
Registered User
 
Join Date: Apr 2002
Location: Germany
Posts: 5,394
It's rather obvious. The formula is laid out for black=0, white=255. But in YV12 with TV levels, it's black=16, white=235.

Replacing all "256" with "236 16 -", and all "x" or "y" with "x 16 -" and "y 16 -" respectively, should result in a correct screen formula for 16-235 TV scale.

Code:
236 16 - 236 16 - x 16 - - 236 16 - y 16 - - * 236 16 - / -

In your 2nd script line ... do you really expect mt_lutxy to reckognize the letters "U" and "L"?
__________________
- We´re at the beginning of the end of mankind´s childhood -

My little flickr gallery. (Yes indeed, I do have hobbies other than digital video!)
Didée is offline   Reply With Quote
Old 25th March 2011, 15:45   #4  |  Link
Dogway
Registered User
 
Join Date: Nov 2009
Posts: 1,041
Yes, you are right, I didnt pay attention to that point. I guess then the formula becomes rather tricky if done mt_lutxy.
Dogway is offline   Reply With Quote
Old 25th March 2011, 15:49   #5  |  Link
Dogway
Registered User
 
Join Date: Nov 2009
Posts: 1,041
halooo Didée; soo fast lol. I was actually trying to replace 256 with 219, but I dont understand plish notation so it is more a try and cross fingers+waste of time. Thanks!
U and L are just the variables. I posted them as they were in the webpage for reference. I wondered if that ".../255 ***" meant something, although it didnt got me an error.

edit=result is a bit dark, still testing...

Last edited by Dogway; 25th March 2011 at 15:55.
Dogway is offline   Reply With Quote
Old 25th March 2011, 15:57   #6  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,406
Quote:
Originally Posted by Didée View Post
Replacing all "256" with "236 16 -", and all "x" or "y" with "x 16 -" and "y 16 -" respectively, should result in a correct screen formula for 16-235 TV scale.
Not quite. You also have to add 16 back into the final result, requiring " 16 +" at the end.
Quote:
Originally Posted by Dogway View Post
U and L are just the variables. I posted them as they were in the webpage for reference. I wondered if that ".../255 ***" meant something, although it didnt got me an error.
One of the 'features' of Masktools is that it does not check the validity of expressions and just returns garbage (or crashes) instead of reporting an error.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 25th March 2011, 16:04   #7  |  Link
Dogway
Registered User
 
Join Date: Nov 2009
Posts: 1,041
@Gavino: Gracias! worked like charm. What I didn't know was that 255 ***. Of course in the practice I replaced U and L with x and y. At least I know that

edit: In gratitude just wanted to share my little function for what this was. Didn't test it deeply so it'll mostly contain errors.
Code:
FUNCTION Logo(clip clip,string path, int "x", int "y",int "length", bool "alpha",int "start",float "Opac",int "I",int "O",float "blur"){

path=string(path)
alpha=default(alpha,true)
x=default(x, 0)
y=default(y, 0)
start=default(start, 0)
length=default(length, 50)
I=default(I, 20)
O=default(O, 20)
Opac=default(Opac, 1.0)
Sblur=default(blur, 0.0)

logo0=CoronaSequence(path).trim(0,length).FadeIn(I).FadeOut(O)
logo0a=logo0.addborders(x,y,clip.width,clip.height).crop(0,0,-logo0.width-x,-logo0.height-y).blur(Sblur)
logo1=logo0a.converttoyv12().assumefps(Framerate(Clip))

video0=clip.trim(0,start == 1 ? -1 : start-1)
video1=clip.trim(start,start+length-1)
video2=clip.trim(start+length,0)

msk=ShowAlpha(logo0a,"rgb").converttoyv12

video1 = (alpha==true) ?
\   mt_merge(video1,logo1,mt_lut(msk," x 16 - "+String(Opac)+" * "),luma=true)
\ : mt_lutxy(video1,logo1,Y=3, U=2, V=2,
\  "236 16 - 236 16 - x 16 - - 236 16 - y 16 - - * 236 16 - / - 16 +  "+String(Opac)+" * x 1 "+String(Opac)+" - * + ")

video=start >0 ? video0+video1+video2 : video1+video2
return video}

Last edited by Dogway; 26th March 2011 at 09:11.
Dogway is offline   Reply With Quote
Old 26th March 2011, 11:05   #8  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,406
Quote:
Originally Posted by Gavino View Post
I've never heard of mt_infix - do you mean mt_polish?
The call could be written as:
mt_lutxy(a,b,mt_polish("255 - (255-x)*(255-y)/255"),Y=3, U=2, V=2)
I've discovered mt_infix converts from polish to infix, so your original code would not have worked, even without the "***".

Quote:
Originally Posted by Dogway View Post
edit: In gratitude just wanted to share my little function for what this was. Didn't test it deeply so it'll mostly contain errors.
Code:
...
logo0=CoronaSequence(path).trim(0,length).FadeIn(I).FadeOut(O)
...
msk=ShowAlpha(logo0a,"rgb").converttoyv12

video1 = (alpha==true) ?
\   mt_merge(video1,logo1,mt_lut(msk," x 16 - "+String(Opac)+" * "),luma=true)
...
When using alpha, your mask is set up wrong, eg alpha mask 255 becomes 219.
Also, logo0 has the wrong number of frames (length+3 instead of length).
You want:
Code:
logo0=CoronaSequence(path).trim(0,length-1).FadeIn0(I).FadeOut0(O)
...
msk=ShowAlpha(logo0a,"YV12")

video1 = (alpha==true) ?
\   mt_merge(video1,logo1,mt_lut(msk,"x "+String(Opac)+" * "),luma=true)
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 26th March 2011, 11:33   #9  |  Link
Dogway
Registered User
 
Join Date: Nov 2009
Posts: 1,041
Thanks thanks a lot, maybe thats the reason of the "darkening" of fadein fadeout, before/after disappearing. Good tips
I also had realised about mt_infix, I tested after that with mt_polish...
I rely on blur() but do you think 0.0 is a no-operator? should I better use GaussianBlur?

I updated the function:
Code:
FUNCTION Logo(clip clip,string path, int "x", int "y",int "start",int "length", bool "alpha",float "Opac",int "I",int "O",float "blur")
{
path=string(path)
alpha=default(alpha,true)
x=default(x, 0)
y=default(y, 0)
start=default(start, 0)
length=default(length, 50)
I=default(I, 20)
O=default(O, 20)
Opac=default(Opac, 1.0)
Sblur=default(blur, 0.0)

logo0=CoronaSequence(path).trim(0,length-1).FadeIn0(I).FadeOut0(O)
logo0a=logo0.addborders(x,y,clip.width,clip.height).crop(0,0,-logo0.width-x,-logo0.height-y).blur(Sblur)
logo1=logo0a.converttoyv12().assumefps(Framerate(Clip))

video0=clip.trim(0,start == 1 ? -1 : start-1)
video1=clip.trim(start,start+length-1)
video2=clip.trim(start+length,0)

video1 = (alpha==true) ?
\   mt_merge(video1,logo1,mt_lut(ShowAlpha(logo0a,"YV12")," x "+String(Opac)+" * "),luma=true)
\ : mt_lutxy(video1,logo1,Y=3, U=2, V=2,
\  "236 16 - 236 16 - x 16 - - 236 16 - y 16 - - * 236 16 - / - 16 +  "+String(Opac)+" * x 1 "+String(Opac)+" - * + ")

video=start >0 ? video0+video1+video2 : video1+video2

return video}

Last edited by Dogway; 26th March 2011 at 11:57.
Dogway is offline   Reply With Quote
Old 26th March 2011, 11:59   #10  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,406
Blur(0.0) is a no-op. The code is optimised and just returns the input clip.
Regarding GaussianBlur, it depends what sort of effect you want. The range of Blur() is limited to 1.58 and even repeating this has a limited effect, so if you want to blur more you have to use a gaussian.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 27th March 2011, 06:47   #11  |  Link
Dogway
Registered User
 
Join Date: Nov 2009
Posts: 1,041
Code:
logo0 =CoronaSequence(path).trim(0,end-start-1).FadeIn0(I).FadeOut0(O)
logo0a=logo0.addborders(x,y,clip.width,clip.height).crop(0,0,-logo0.width-x,-logo0.height-y).blur(Sblur)
logo1 =logo0a.converttoyv12().assumefps(Framerate(Clip))

s=ShowAlpha(logo0a,"YV12")

video1 = AverageLuma(s) == float(HexValue("FFFFFF"))  ?
\   mt_merge(clip.trim(start,end-1),logo1,mt_lut(s," x "+String(Opac)+" * "),luma=true)
\ : mt_lutxy(clip.trim(start,end-1),logo1,Y=3, U=2, V=2,
\  "236 16 - 236 16 - x 16 - - 236 16 - y 16 - - * 236 16 - / - 16 +  "+String(Opac)+" * x 1 "+String(Opac)+" - * + ")

return start >0 ? clip.trim(0,start == 1 ? -1 : start-1)+video1+clip.trim(end,0) : video1+clip.trim(end,0)}
I updated the code a bit, mostly nesting functions, do you think this is better for RAM optimization?
Also I want to automatically detect alpha so I can remove the alpha parameter.
As theres are no clip properties associated to alpha evaluation, I try to compare the result from the average of ShowAlpha to White, if false then it has alpha.
Problem here is Im getting errors ("Invalid arguments")when I try AverageLuma, I think because some the ISSE requeriments:
AverageLuma(ShowAlpha(logo0a,"YV12")) == float(HexValue("FFFFFF"))

Last edited by Dogway; 27th March 2011 at 07:08.
Dogway is offline   Reply With Quote
Old 27th March 2011, 10:47   #12  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,406
Quote:
Originally Posted by Dogway View Post
I updated the code a bit, mostly nesting functions, do you think this is better for RAM optimization?
It can be in some cases. Nested function calls do not save anything per se, but if you have filters that are only used on a conditional branch, it can help to avoid calling them unnecessarily outside the condition. (But filters like Trim use very little memory anyway.)
Quote:
Also I want to automatically detect alpha so I can remove the alpha parameter.
As theres are no clip properties associated to alpha evaluation, I try to compare the result from the average of ShowAlpha to White, if false then it has alpha.
Problem here is Im getting errors ("Invalid arguments")when I try AverageLuma, I think because some the ISSE requeriments:
AverageLuma(ShowAlpha(logo0a,"YV12")) == float(HexValue("FFFFFF"))
The immediate problem here is that AverageLuma is not a clip property, but a frame property, so you can only use it inside a run-time filter such as ScriptClip.
However, you can't reliably detect the presence of alpha by looking at single frames - you would need to check the whole clip for the existence of some frames with AverageLuma not equal to zero or 255 ($ff, not $ffffff). Too complicated to be worth doing, I think.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 27th March 2011, 19:43   #13  |  Link
Dogway
Registered User
 
Join Date: Nov 2009
Posts: 1,041
I read that page before but thanks to your guidance I think I got it working.
The only pitfall here is in case the logo is animated, and the sample frame to take the alpha from (Default FadeIn(I)) has alpha set to 100% opacity. Its quite unlikely, but Im done in this regard. Maybe only that ConditionalFilter feels a bit unstable, like in the same boat as layer, or overlay...

The only last part I want to fix is making chroma work in blending modes.
The function where I took the blend mode from is Blend_MT_alpha3, but even in that function, chroma seems broken.

Code:
FUNCTION Logo(clip clip,string path, int "x", int "y",int "start",int "end", float "Opac",int "I",int "O",float "blur",string "mode", bool "anim_gif")
{
path=string(path)
x=default(x, 0)
y=default(y, 0)
start=default(start, 0)
end=default(end, 100)
I=default(I, 20)
O=default(O, I)
Opac=default(Opac, 1.0)
Sblur=default(blur, 0.0)
gif=default(anim_gif,false)
mode=default(mode,"Screen")


logo0 = gif == false ? CoronaSequence(path,start=start,stop=end-1).mmod2.FadeIn0(I).FadeOut0(O)
\  : ImmaRead(path,start=start,end=end-1,animation=true).mmod2.FadeIn0(I).FadeOut0(O)
logo0a=logo0.addborders(x,y,clip.width,clip.height).crop(0,0,-logo0.width-x,-logo0.height-y).blur(Sblur)
logo1 =logo0a.converttoyv12().assumefps(Framerate(Clip))

video1=ConditionalFilter(ShowAlpha(logo0,"YV12").trim(I+1,I),
\   mt_lutxy(clip.trim(start,end-1),logo1,Y=3, U=2, V=2,
\ (mode=="Screen")    ? "236 16 - 236 16 - x 16 - - 236 16 - y 16 - - * 236 16 - / - 16 +  "+String(Opac)+" * x 16 - 1 "+String(Opac)+" - * + "
\:(mode=="Multiply") ? "x 16 - y 16 - * 236 16 - / 16 + "+String(Opac)+" * x 16 - 1 "+String(Opac)+" - * + " : Assert(false, "Unsupported Blending Mode")
\), mt_merge(clip.trim(start,end-1),logo1,mt_lut(ShowAlpha(logo0a,"YV12")," x "+String(Opac)+" * "),luma=true),"AverageLuma()","==","255",false)

return start >0 ? clip.trim(0,start == 1 ? -1 : start-1)+video1+clip.trim(end,0) : video1+clip.trim(end,0)}
Edit: I reworked the function completly, I fixed some things, and added option for Over blending mode. Syntax is awful with my limited knowledge... so Im sure the code can be optimized far far better. I really just would like to fix the chroma blending, I tried everything but my guess is it has to do with the polish notation formula.
Edit2:I read a paper. Im going to try to compute the effect in RGB and add the difference to my YUV clip. Maybe there's less degradation in this way... I might also fix something I saw when I got time.
Edit3: I didn't come to think masktools is only for YV12, so I guess chroma blending stays unfunctional, unless I find a way to compute blend modes in RGB. Also I updated/fixed/optimized the code for the new workaround, now this is a working release. Enjoy it.

(Old)
Code:
FUNCTION Logo(clip clip,string path, int "x", int "y",int "start",int "end", float "Opac",int "I",int "O",float "blur",string "mode",bool "matte",bool "anim_gif")
{
path=string(path)
x=default(x, 0)
y=default(y, 0)
start=default(start, 0)
end=default(end, 100)
I=default(I, 20)
O=default(O, I)
Opac=default(Opac, 1.0)
Sblur=default(blur, 0.0)
gif=default(anim_gif,false)
mode=default(mode,"Over")
matte=default(matte,false)


logo0 = gif == false ? CoronaSequence(path,start=start,stop=end-1).mmod2.FadeIn0(I).FadeOut0(O)
\                    : ImmaRead(path,start=start,end=end-1,animation=true).mmod2.FadeIn0(I).FadeOut0(O)
logo0a=logo0.addborders(x,y,clip.width,clip.height).crop(0,0,-logo0.width-x,-logo0.height-y).blur(Sblur)
logo1 =logo0a.converttoyv12().assumefps(Framerate(Clip))

msk = matte == false ? ShowAlpha(logo0a,"YV12")
\                    : ShowAlpha(logo0a,"YV12").lanczosresize(logo0a.width*3,logo0a.height*3).mt_inpand(mode="both").LanczosResize(logo0a.width,logo0a.height)
org=clip.trim(start,end-1)
screen="236 16 - 236 16 - x 16 - - 236 16 - y 16 - - * 236 16 - / - "+String(Opac)+" * x 16 - 1 "+String(Opac)+" - * + 16 + "
multiply=" x 16 - y 16 - * 236 / "+String(Opac)+" * x 16 - 1 "+String(Opac)+" - * + 16 + "

video1 =
\ (mode=="Screen")   ? mt_merge(org,mt_lutxy(org,logo1,Y=3, U=2, V=2,screen)  ,msk,luma=true)
\:(mode=="Multiply") ? mt_merge(org,mt_lutxy(org,logo1,Y=3, U=2, V=2,multiply),msk,luma=true)
\:(mode=="Over")     ? mt_merge(org,logo1,mt_lut(msk," x "+String(Opac)+" * "),luma=true)
\:Assert(false, "Unsupported Blending Mode")

return start >0 ? clip.trim(0,start == 1 ? -1 : start-1)+video1+clip.trim(end,0) : video1+clip.trim(end,0)}

function mmod2(clip c){
bh = 2 - ((c.Width()-1)%2 + 1)
bv = 2 - ((c.Height()-1)%2 + 1)
l = bh/2
l = c.IsYUV() && l%2 != 0 ? l-1 : l
r = bh - l
t = bv/2
t = c.IsYV12() && t%2 != 0 ? t-1 : t
b = bv - t
c.crop(l,t,-r,-b)}
(Updated)
Logo9.0.avsi

Last edited by Dogway; 24th May 2011 at 17:57. Reason: update to 9.0 link
Dogway is offline   Reply With Quote
Reply

Tags
blend mode, logo, screen, watermark

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 01:45.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2020, vBulletin Solutions Inc.