Log in

View Full Version : New Script: Drawrect 0.6


Pages : 1 [2]

redfordxx
1st December 2011, 09:51
, due to the way mt_merge works.
It calculates (x*256+128)/256 and when x=255 (when drawing a white line), I'm getting 254 back, so it's NOT drawing the correct colors.
I'll have to investigate later.

Look here (http://forum.doom9.org/showthread.php?t=163018) try RMerge, and you are welcome to write feedback to that thread. I would appreciate it before I am adding the SSE optimization to this filter.

I had here and there also issues with this mt_merge-->254 thing, so I just btw made my own merge;-)
Tell me if this meets your needs in that case:
RMerge(c1,c2,m,mode=256,sse=0) #sse=0 necessary before I add optimization

jmac698
4th August 2014, 09:26
I needed a way to draw shapes and found my own script again.

Just to summarize the thread,

1 I investigated imagemagick and subtitles renderers; both require specifying colours only in RGB

2 Some YUV colours cannot be specified in RGB without using negative values, and neither of the above tools allow this

3 Even the range of YUV colours which can be made from positive RGB values, can't all be made, because of precision loss in the mapping between coordinate systems. (think of communicating an x,y coordinate from another coordinate system that's slanted 45 degrees; (2,2) in the slanted version maps to (1.414,1.414) in the second version, so you can see how gaps can occur).

4 In summary, there is no way to use positive, 8bit RGB colours to specify all video YUV colours.

5 I need opacity to range 0-256 because otherwise, there is an error when using all-white (white=255, 99.6% opacity=255/256, 255*255/256=254. A fully opaque white should give 255. The small error of 254 means that further masking steps won't match when looking for 255.

6 Drawing shapes in a paint program still has the same problem; you can only specify colours in RGB. Also, the shapes I need would be very tedious to create by hand - imagine drawing standard colourbars, or a frequency sweep (something which can only be calculated).

7 I'd like to expand these tools to draw sinewaves, circles and special YUV colours like I/Q (from the standard colourbars).

8 You can import raw YUV in imagemagick but it's expecting a specific raw format, which I haven't found documented. There are no options to specify variations of the format.

ps I'm actually working on an improved de-comet algorithm now, and I *still* have no better way to programaticaly create YUV test patterns

TheFluff
4th August 2014, 16:48
5 I need opacity to range 0-256 because otherwise, there is an error when using all-white (white=255, 99.6% opacity=255/256, 255*255/256=254. A fully opaque white should give 255. The small error of 254 means that further masking steps won't match when looking for 255.

Why on earth would you be dividing by 256? Since when does 256 fit in an unsigned 8-bit byte?

Also, here's some food for thought: RGB24 and YUV 444 both happen to have 24 bits per pixel. What a neat coincidence! If only there was an AssumePixelFormat() (hint: it's probably trivial to write). Of course, blending doesn't work the same in YUV as it does in RGB but at least it gives you a trivial way to draw shapes using existing tools that only support RGB. Overlay() should solve the rest.

jmac698
4th August 2014, 21:12
AssumePixelFormat would have been very useful when I was trying to do operations in YUV like http://forum.doom9.org/archive/index.php/t-108018.html. Then I could use RGB calculations and move back to YUV (but that was before I discovered masktools). I remember going through all sorts of hoops to perfectly copy YUV planes <> to RGB. I believe it was the use of YtoUV, UtoY, VtoY, and using greyscale and mergeRGB. Now I wish masktools worked in RGB! The problem remains.

I'm allowing an opacity range up to 256 for the same reason http://avisynth.nl/index.php/Overlay does, to allow fully transparent and fully opaque. 255/256 refers to the internal calculation that is done; the value of the mask is interpreted as a fraction of 256 (and yes, Overlay needs to do 16bit calculations).

You also have to be aware that Overlay does extra manipulations that I want to avoid (which is also why it's slow), such as colour interpolation.

ps anyhow, I got the job done now. I made my test video and solved a programming problem I was having. Avisynth to the rescue :) I made progress on my de-comet plugin, the problem is cluster analysis of Guassian mixing, and I want to use maximum expectation.

TheFluff
4th August 2014, 22:42
I'm allowing an opacity range up to 256 for the same reason http://avisynth.nl/index.php/Overlay does, to allow fully transparent and fully opaque.

255/255 == 1
0/255 == 0

Please explain to me in what way this does not allow fully transparent and fully opaque.

I'm not exactly sure why Overlay() uses 0-256 internally but a random guess says it's to get a right shift by 8 instead of a division by 255 in a calculation in an inner loop. In other words, it's probably a 90's optimization that doesn't really matter today, and I suspect it's actually off-by-one in some situations. It's most definitely not to allow "fully transparent and fully opaque"; any scale would allow that.

As Gavino said three years ago:
I don't see the point of having 0-256 instead of 0-255.
The latter seems more natural to me and the former introduces an unnecessary special case into the code for no appreciable gain.

You also have to be aware that Overlay does extra manipulations that I want to avoid (which is also why it's slow), such as colour interpolation.

I'm actually not at all aware of these "extra manipulations". It does upconvert to YV24 internally, but in this case we're discussing your input is already YV24, so I really don't understand what you're talking about. You could also just use mt_merge if it makes you happier, it does mostly the same thing except only in YV12. The main reasons overlay is slower are that it doesn't have a SIMD implementation and that it processes full chroma resolution.

edit: I was right about the 128 thing. mt_merge uses the same wonky 256 and like I suspected it's sometimes off-by-one; see https://github.com/tp7/masktools/issues/12

Wilbert
5th August 2014, 19:18
Also, here's some food for thought: RGB24 and YUV 444 both happen to have 24 bits per pixel. What a neat coincidence! If only there was an AssumePixelFormat() (hint: it's probably trivial to write). Of course, blending doesn't work the same in YUV as it does in RGB but at least it gives you a trivial way to draw shapes using existing tools that only support RGB. Overlay() should solve the rest.
You need to flip and convert to planar too, but it remains trivial ;)

I guess the following should also work:

rgb_clip = ...
y = rgb_clip.ShowRed("Y8") # not documented yet
u = rgb_clip.ShowGreen("Y8")
v = rgb_clip.ShowBlue("Y8")
YToUV(y,u,v)

colours
6th August 2014, 08:07
Wilbert: actually, the U and V planes come before the Y plane for YToUV, so it should be YToUV(u,v,y) if the R/G/B planes are used to store Y/U/V information.

StainlessS
8th August 2015, 20:27
Creates a Marker

AVISource("E:\V\StarWars.avi")
Blk = Last.Blankclip(width=64,height=64,Length=1)
#InFix = RT_string("(x==0|x==%d|y==0|y==%d)?128:0",Blk.Width-1,Blk.Height-1)
InFix = RT_string("((x==0|x==%d|y==0|y==%d)&(x<4|x>=%d)&(y<4|y>=%d))?255:0",Blk.Width-1,Blk.Height-1,Blk.Width-4,Blk.Height-4)
Marker=Blk.mt_lutspa(relative = false,yExpr=mt_Polish(InFix), chroma = "128")

Overlay(Marker,x=(Width-Marker.width)/2,y=(Height-Marker.Height)/2,Mode="Exclusion")

return last


sort of like a square with only corners drawn

__ __
| |


|_ _|



EDIT: Here as function to create mask for Overlay, Hit=false for some kind of 'Miss' and true for some kind of 'Hit' (detect).


Function RectMarker(clip c,int W, Int H,Bool "Hit") {
# req RT_Stats & mt_tools_2, Returns YV12 frame WxH same FPS as c and without audio
Hit=Default(hit,False)
InFix = (Hit)
\ ? RT_string("(((x<=1|x>=%d|y<=1|y>=%d)&(x<4|x>=%d)&(y<4|y>=%d)|(x==0|x==%d|y==0|y==%d)))?255:0", W-2,H-2,W-4,H-4,W-1,H-1)
\ : RT_string("((x<=1|x>=%d|y<=1|y>=%d)&(x<4|x>=%d)&(y<4|y>=%d))?255:0", W-2,H-2,W-4,H-4)
c.Blankclip(width=W,height=H,Length=1,pixel_type="YV12").Killaudio
return mt_lutspa(relative = false,yExpr=mt_Polish(InFix), chroma = "128")
}


rough usage with some missing code


# ...

MissMask = RectMarker(c,BlkW,BlkH,false)
HitMask = RectMarker(c,BlkW,BlkH,true)
MissMark = MissMask.BlankClip(Color=MissColor)
HitMark = HitMask.BlankClip(Color=HitColor)

# ...

(hit!=0) ? Overlay((hit==2)?HitMark:MissMark,x=x,y=y,Mask=(hit==2)?HitMask:MissMask,Mode="Blend") : NOP

StainlessS
2nd April 2017, 12:39
Small update to prev post Rectal Marker, for marking your territory or something. :)


Function Elliptical_Marker(clip c,int W, Int H,Bool "Soft") {
# Req mt_tools_2, Returns YV12 frame WxH same FPS as c and without audio
Soft=Default(Soft,False)
# INFIX_H="(((x-.5)^2 +(y-.5)^2) < .25 ? 255 : 0" # INFIX: Elliptical Disk (Hard Edge) :: mode = "relative", Radius=0.5, Rad^2=0.25 :: SOFT_Inner rad:(Rad*0.9)^2~=0.2
# INFIX_S="((x-.5)^2+(y-.5)^2)<.2?255:(((x-.5)^2+(y-.5)^2)<.25?(.25-((x-.5)^2+(y-.5)^2))*5100):255" # INFIX: Elliptical Disk (Soft Edge) :: (.25-0.2)*5100=255 : (.25-.25)*5100=0.0] :: mode="relative", 0.25=1.0 : 0.2~=0.9
rpn = (!Soft)
\ ? "x 0.5 - 2 ^ y 0.5 - 2 ^ + 0.25 < 255 0 ?" [* RPN: Elliptical Disk [Hard Edge] *]
\ : "x 0.5 - 2 ^ y 0.5 - 2 ^ + 0.2 < 255 x 0.5 - 2 ^ y 0.5 - 2 ^ + 0.25 < 0.25 x 0.5 - 2 ^ y 0.5 - 2 ^ + - 5100 *" [* RPN: Elliptical Disk [Soft Edge] *]
c.Blankclip(width=W,height=H,Length=1,pixel_type="YV12").Killaudio
return Last.mt_lutspa(mode = "relative", expr = rpn, chroma = "-128" )
}

EDITED:

EDIT: And an EllipticalDisk marker, used in this case as an Overlay mask.

Function Elliptical_Marker(clip c,int W, Int H,Bool "Soft") {
# Req mt_tools_2, Returns YV12 frame WxH same FPS as c and without audio
Soft=Default(Soft,False)
# INFIX_H="(((x-.5)^2 +(y-.5)^2) < .25 ? 255 : 0" # INFIX: Elliptical Disk (Hard Edge) :: mode = "relative", Radius=0.5, Rad^2=0.25 :: SOFT_Inner rad:(Rad*0.9)^2~=0.2
# INFIX_S="((x-.5)^2+(y-.5)^2)<.2?255:(((x-.5)^2+(y-.5)^2)<.25?(.25-((x-.5)^2+(y-.5)^2))*5100):255" # INFIX: Elliptical Disk (Soft Edge) :: (.25-0.2)*5100=255 : (.25-.25)*5100=0.0] :: mode="relative", 0.25=1.0 : 0.2~=0.9
rpn = (!Soft)
\ ? "x 0.5 - 2 ^ y 0.5 - 2 ^ + 0.25 < 255 0 ?" [* RPN: Elliptical Disk [Hard Edge] *]
\ : "x 0.5 - 2 ^ y 0.5 - 2 ^ + 0.2 < 255 x 0.5 - 2 ^ y 0.5 - 2 ^ + 0.25 < 0.25 x 0.5 - 2 ^ y 0.5 - 2 ^ + - 5100 *" [* RPN: Elliptical Disk [Soft Edge] *]
c.Blankclip(width=W,height=H,Length=1,pixel_type="YV12").Killaudio
return Last.mt_lutspa(mode = "relative", expr = rpn, chroma = "-128" )
}


Avisource("F:\V\StarWars.avi") # Source YV12
Sym=Avisource("F:\V\XMen2.avi").Trim(5000,0) # Overlay clip

W=(Width/16) * 4
H=(Height/16) * 4
Sym=Sym.BilinearResize(W,H)
El = Sym.EllipticalMarker(W,H,true).Loop(Sym.Framecount)
Return OverlayClip(Last,Sym,S=100,E= -Sym.FrameCount,x= -(Sym.Width+16),y= -(Sym.Height+16),mask=El)

EDITED:

EDIT: Changed to Soft edge disk.

StainlessS
3rd April 2017, 04:00
Script to make any movie under the sun, seem interesting. [EDIT: Req Masktools v2.0]


# BouncingBallMovie.avs

Function Elliptical_Marker(clip c,int W, Int H,Bool "Soft") {
# Req mt_tools_2, Returns YV12 frame WxH same FPS as c and without audio
Soft=Default(Soft,False)
# INFIX_H="(((x-.5)^2 +(y-.5)^2) < .25 ? 255 : 0" # INFIX: Elliptical Disk (Hard Edge) :: mode = "relative", Radius=0.5, Rad^2=0.25 :: SOFT_Inner rad:(Rad*0.9)^2~=0.2
# INFIX_S="((x-.5)^2+(y-.5)^2)<.2?255:(((x-.5)^2+(y-.5)^2)<.25?(.25-((x-.5)^2+(y-.5)^2))*5100):255" # INFIX: Elliptical Disk (Soft Edge) :: (.25-0.2)*5100=255 : (.25-.25)*5100=0.0] :: mode="relative", 0.25=1.0 : 0.2~=0.9
rpn = (!Soft)
\ ? "x 0.5 - 2 ^ y 0.5 - 2 ^ + 0.25 < 255 0 ?" [* RPN: Elliptical Disk [Hard Edge] *]
\ : "x 0.5 - 2 ^ y 0.5 - 2 ^ + 0.2 < 255 x 0.5 - 2 ^ y 0.5 - 2 ^ + 0.25 < 0.25 x 0.5 - 2 ^ y 0.5 - 2 ^ + - 5100 *" [* RPN: Elliptical Disk [Soft Edge] *]
c.Blankclip(width=W,height=H,Length=1,pixel_type="YV12").Killaudio
return Last.mt_lutspa(mode = "relative", expr = rpn, chroma = "-128" )
}



Function DrawBounce(clip c) { # Physical window coords
Squash = (G_bounceY == 0)
B = (Squash) ? G_Squashed_Ball : G_Ball
Xrel = (b.Width - G_Ball.Width) / 2
phyX = Round(G_bounceX * (c.Width - G_Ball.Width - xrel))
phyY = Round((1.0 - G_bounceY) * c.Height) - B.Height
(G_Sym.IsClip)
\ ? c.Overlay(Squash?G_Sym_Squashed:G_Sym,x=phyX,y=phyY,mask=B)
\ : c.OverLay(B.BlankClip(Color=G_BALLCOLOR,Length=1),x=phyX,y=phyY,Mask=B)
return Last
}

Function MoveBounce(clip c) { # Logical coords (0.0 -> 1.0, cartesian)
bX = G_bounceX + G_bounceXstep
Global G_bounceXstep = (0.0 < bX < 1.0) ? G_bounceXstep : -G_bounceXstep # Wall Bounce, Switch direction next time
Global G_bounceX = (0.0 > bX) ? 0.0 : (bX > 1.0) ? 1.0 : bX
bY = Sin(G_bounceAngle) * G_bounceMax
Global G_bounceY = (bY < 0.0) ? 0.0 : bY
bAng = G_bounceAngle + G_bounceAngleStep
Global G_bounceAngle = (bAng > PI) ? 0.0 : bAng
return c.DrawBounce
}

Function RandF() {return Rand / 32767.0}

######
#Avisource("F:\V\SexInTheCity.avi")
#Avisource("F:\V\XMen2.avi")
ColorBars.ShowFrameNumber.KillAudio

Rand(Seed=True)
###
Global G_BALLCOLOR = $C020FF
BALLSZ = 128
SQUISH = 8
SOFT = True
SYM = True # False = Plain bouncing ball
### GENERAL CONTROL for bouncer (1.0=norm)
SPEED = 1.0
BOUNCEHEIGHT = 1.0
###
Global G_bounceMax = BOUNCEHEIGHT * (1.0-Float(BALLSZ)/Height)
Global G_bounceXstep = 0.005 * SPEED # Xpos increment
Global G_bounceAngleStep = (0.01 + RandF * 0.04) * SPEED # Step angle
### Start pos
Global G_bounceX = RandF # Current X position
Global G_bounceY = RandF # Current Y position
Global G_bounceAngle = RandF * PI
######
Global G_Ball = Last.Elliptical_Marker(BALLSZ,BALLSZ,SOFT)
Global G_Squashed_Ball = Last.Elliptical_Marker(BALLSZ+SQUISH,BALLSZ-SQUISH,SOFT)
Global G_Sym = (SYM) ? BilinearResize(BALLSZ,BALLSZ) : 0
Global G_Sym_Squashed = (SYM) ? BilinearResize(G_Squashed_Ball.Width,G_Squashed_Ball.Height): 0

ScriptClip("return MoveBounce")

EDITED

StainlessS
28th December 2019, 18:06
Prev 2 posts, fixed a couple of probs.


Function Elliptical_Marker(clip c,int W, Int H,Bool "Soft") {
# Req mt_tools_2, Returns YV12 frame WxH same FPS as c and without audio
Soft=Default(Soft,False)
# INFIX_H="(((x-.5)^2 +(y-.5)^2) < .25 ? 255 : 0" # INFIX: Elliptical Disk (Hard Edge) :: mode = "relative", Radius=0.5, Rad^2=0.25 :: SOFT_Inner rad:(Rad*0.9)^2~=0.2
# INFIX_S="((x-.5)^2+(y-.5)^2)<.2?255:(((x-.5)^2+(y-.5)^2)<.25?(.25-((x-.5)^2+(y-.5)^2))*5100):255" # INFIX: Elliptical Disk (Soft Edge) :: (.25-0.2)*5100=255 : (.25-.25)*5100=0.0] :: mode="relative", 0.25=1.0 : 0.2~=0.9
rpn = (!Soft)
\ ? "x 0.5 - 2 ^ y 0.5 - 2 ^ + 0.25 < 255 0 ?" [* RPN: Elliptical Disk [Hard Edge] *]
\ : "x 0.5 - 2 ^ y 0.5 - 2 ^ + 0.2 < 255 x 0.5 - 2 ^ y 0.5 - 2 ^ + 0.25 < 0.25 x 0.5 - 2 ^ y 0.5 - 2 ^ + - 5100 *" [* RPN: Elliptical Disk [Soft Edge] *]
c.Blankclip(width=W,height=H,Length=1,pixel_type="YV12").Killaudio
return Last.mt_lutspa(mode = "relative", expr = rpn, chroma = "-128" )
}

was chroma = "128", should be chroma = "-128". [did throw error in current masktools - thanx P]
Converted to RPN, mt_Polish dont work in current Masktools on XP.
Added comments to Infix notation expressions. (and changed infix & rpn expressions slightly).

kedautinh12
17th October 2022, 01:56
Latest ver:
https://github.com/Asd-g/AviSynthPlus-Scripts/blob/master/Drawrect_.avsi