View Full Version : Spinner Plugin
vcmohan
3rd August 2008, 15:07
Spinner: This plugin rotates a frame or selected part of it through any desired angle. The rotation axis coordinates and angle of rotation can be in floating point. Option for varying parameters linearly along clip and specify a rectangular area to undergo rotation is available. Precision may be nearest neighbour, bilinear or bicubic interpolation. If a thin rectangle outside axis of rotation is specified , it appears as cartwheeling.
I read sometime back that the test for good rotation technique is to rotate image several times (say 60 degrees each time for 6 times) and compare with original by subtract. I got surprising results. Nearest neighbour option resulted in random noise as output. Bilinear has in the difference strong elements of the image. Bicubic has the strongest image elements.
Possibly this is to be expected, but still gives the impression that bicubic is the worst of the lot.
Either my understanding is not correct or my implementation is defective?
Gavino
3rd August 2008, 16:32
Putting the case for the defence, ...
you could interpret the results another way - nearest neighbour adds random noise to the 'correct' result, while the others are more highly correlated with the original, with bicubic best of all!
I'm just speculating, I don't know what you should expect theoretically. The real test of course is - which of the three looks more like the original?
Fizick
3rd August 2008, 19:49
vcmohan,
Please rename your plugin. I have Rotate plugin too. It is confused.
tin3tin
3rd August 2008, 22:28
Just thinking out loud... how about using OpenGL for something like this(and other things)?.
Anyway it sure would be great with an OpenGl Plugin. :cool:
vcmohan
4th August 2008, 11:08
vcmohan,
Please rename your plugin. I have Rotate plugin too. It is confused.
Sorry for that. I changed the name to Spinner even though I did not like the name much.
45tripp
4th August 2008, 11:11
what's wrong with 'Rotator', in that case?
Fizick
4th August 2008, 16:28
Thanks!
I will look to it. I tryed set some compatibility.
Can anybody make a speed test of various rotation plugins?
mikeytown2
4th August 2008, 19:15
Speed/Quality Test Code
a = ColorBars(1024,768).Trim(0,99)
Animate(0, a.framecount()-1, "Angle", a, float(-500), 0, a, float(510), 0)
last + Animate(0, a.framecount()-1, "Angle", a, float(510), 0, a, float(520), 0)
last + Animate(0, a.framecount()-1, "Angle", a, float(-500), 1, a, float(510), 1)
last + Animate(0, a.framecount()-1, "Angle", a, float(510), 1, a, float(520), 1)
last + Animate(0, a.framecount()-1, "Angle", a, float(-500), 2, a, float(510), 2)
last + Animate(0, a.framecount()-1, "Angle", a, float(510), 2, a, float(520), 2)
last + Animate(0, a.framecount()-1, "Angle", a, float(-500), 3, a, float(510), 3)
last + Animate(0, a.framecount()-1, "Angle", a, float(510), 3, a, float(520), 3)
last + Animate(0, a.framecount()-1, "Angle", a, float(-500), 4, a, float(510), 4)
last + Animate(0, a.framecount()-1, "Angle", a, float(510), 4, a, float(520), 4)
last + Animate(0, a.framecount()-1, "Angle", a, float(-500), 5, a, float(510), 5)
last + Animate(0, a.framecount()-1, "Angle", a, float(510), 5, a, float(520), 5)
last + Animate(0, a.framecount()-1, "Angle", a, float(-500), 6, a, float(510), 6)
last + Animate(0, a.framecount()-1, "Angle", a, float(510), 6, a, float(520), 6)
last + Animate(0, a.framecount()-1, "Angle", a, float(-500), 7, a, float(510), 7)
last + Animate(0, a.framecount()-1, "Angle", a, float(510), 7, a, float(520), 7)
Function Angle(clip c, float a, int mode)
{
b = (Round(abs(a)*1000)%360000)/1000.0
d = a < 0 ? 1-(b/360.0) : b/360.0
b = a < 0 ? -b : b
c
mode == 0 ? Subtitle("Orginal (no rotation) " + String(a),align=5) :
\ mode == 1 ? Zoom(angle=string(a)).Subtitle("Zoom " + String(a),align=5) :
\ mode == 2 ? Freeframe("C:\Program Files\AviSynth 2.5\plugins\PetePanSpinZoom.dll",false,0.5,0.5,d,0.2).Subtitle("PetePanSpinZoom " + String(d),align=5) :
\ mode == 3 ? EffectRotation(id=-a, cc=$000000).Subtitle("EffectRotation " + String(-a),align=5) :
\ mode == 4 ? Rotate(a).Subtitle("Rotate " + String(a),align=5) :
\ mode == 5 ? Spinner(angle=a,check=false,bg=false,q=2).Subtitle("Spinner Q=2 " + String(a),align=5) :
\ mode == 6 ? Spinner(angle=a,check=false,bg=false,q=1).Subtitle("Spinner Q=1 " + String(a),align=5) :
\ Spinner(angle=a,check=false,bg=false,q=0).Subtitle("Spinner Q=0 " + String(a),align=5)
}
Zoom() (http://forum.doom9.org/showthread.php?t=49429)
Freeframe() (http://forum.doom9.org/showthread.php?threadid=92174) w/ PetePanSpinZoom (http://www.petewarden.com/PetesPlugins_FreeFrame1.15.zip)
EffectRotation() (http://avisynth.org/vcmohan/EffectsMany/EffectRotation.html)
Rotate() (http://avisynth.org.ru/rotate/rotate.html)
Spinner() (http://avisynth.org/vcmohan/Spinner/Spinner.html)
Speed
None: 28fps
FreeFrame: 16fps
Rotate: 13fps
Spinner Q=0: 12fps
Zoom: 7fps
Spinner Q=1: 6fps
EffectRotation: 5fps
Spinner Q=2: 4fps
Rotate has the best picture quality hands down.
Everything else is ok
Gavino
5th August 2008, 01:12
Function Angle(clip c, float a, int mode) {
b = (Round(abs(a)*1000)%360000)/1000.0
d = a < 0 ? 1-(b/360.0) : b/360.0
b = a < 0 ? -b : b
c
mode == 1 ? Zoom(angle="spline(n, " + String(0) + "," + String(a) + ", " + String(1) + "," + String(a) + ", false)").Subtitle("Zoom " + String(a),align=5) :
Nice idea. A few comments:
- What is the purpose of the second assignment to b? Its value doesn't seem to be used (only a and d are).
- it's a bit unfair on Zoom to call it this way; since the angle is fixed for each invocation, you should just use:
Zoom(angle=string(a))
This should speed it up a bit, although I suspect most of its time goes in pixel manipulation anyway, and not in evaluating the expression string.
- The figures may be misleading wrt the relative speeds because there is a constant overhead of Animate + function call and Subtitle. How about adding a mode 0 which is justSubtitle("Original", align=5) in order to provide the base point.
mikeytown2
5th August 2008, 01:32
b was for the original EffectRotation() because it only took ints as input.
Re-ran Zoom, no speed difference.
This code came from KBE() (http://forum.doom9.org/showthread.php?p=1146653#post1146653)
vcmohan
5th August 2008, 08:01
Just thinking out loud... how about using OpenGL for something like this(and other things)?.
Anyway it sure would be great with an OpenGl Plugin. :cool:
I am absolutely unfamiliar with using explicitly OpenGl. Once I tried to aquaint myself with DirectX but after noting that the documentation/ guide etc for its SDK runs to 475MB gave up.
Regarding speed test by miketown2 , I am not surprised as I have no mmx optimization or any assembler code. I will be shortly adding a couple of options for quality and possibly speed enhancements. Also animate may not be used with Spinner or effectRotation as there are animations within them and are much faster.
Gavino
5th August 2008, 09:05
Also animate may not be used with Spinner or effectRotation as there are animations within them and are much faster.
Zoom also has internal animation using the expression string, but I haven't noticed it being faster than 'Animate'ing a fixed value (though I haven't done any formal comparisons). The expression string is obviously more convenient when you want non-linear variation.
vcmohan
6th August 2008, 02:52
Originally Posted by mikeytown2
Spinner Q=2 picture quality could be improved
On checking my code I found a silly mistake in q = 2 code. It is corrected now in dll (not the source code yet as I am working on it for both q and speed improvements)
For some reason mickeytown2 post does not have the 'quote' button.
mikeytown2
6th August 2008, 03:48
My orginal post had round() in the code for EffectRotation. It's now fixed, sorry about that vcmohan! Q=2 works correctly as well!
Round 2 - "Built in" code.
a = ColorBars(1024,768).Trim(0,99)
x=-500.0
y=510.0
z=520.0
Animate(0, a.framecount()-1, "Angle", a, float(x), 0, a, float(y), 0)
last + Animate(0, a.framecount()-1, "Angle", a, float(y), 0, a, float(z), 0)
last + a.Zoom(angle="spline(n, " + String(0) + "," + String(x) + ", " + String(a.framecount()-1) + "," + String(y) + ", false)", show=true).Subtitle("Zoom " + String(x) + " to " + String(y),align=5)
last + a.Zoom(angle="spline(n, " + String(0) + "," + String(y) + ", " + String(a.framecount()-1) + "," + String(z) + ", false)", show=true).Subtitle("Zoom " + String(y) + " to " + String(z),align=5)
last + Animate(0, a.framecount()-1, "Angle", a, float(x), 2, a, float(y), 2)
last + Animate(0, a.framecount()-1, "Angle", a, float(y), 2, a, float(z), 2)
last + a.EffectRotation(id=-x, cc=$000000, fd=-y).Subtitle("EffectRotation " + String(x) + " to " + String(y),align=5)
last + a.EffectRotation(id=-y, cc=$000000, fd=-z).Subtitle("EffectRotation " + String(y) + " to " + String(z),align=5)
last + a.Rotate(angle=x,start=0,end=a.framecount()-1,endangle=y).Subtitle("Rotate " + String(x) + " to " + String(y),align=5)
last + a.Rotate(angle=y,start=0,end=a.framecount()-1,endangle=z).Subtitle("Rotate " + String(y) + " to " + String(z),align=5)
last + a.Spinner(angle=x,eangle=y,check=false,bg=false,q=2).Subtitle("Spinner Q=2 " + String(x) + " to " + String(y),align=5)
last + a.Spinner(angle=y,eangle=z,check=false,bg=false,q=2).Subtitle("Spinner Q=2 " + String(y) + " to " + String(z),align=5)
last + a.Spinner(angle=x,eangle=y,check=false,bg=false,q=1).Subtitle("Spinner Q=1 " + String(x) + " to " + String(y),align=5)
last + a.Spinner(angle=y,eangle=z,check=false,bg=false,q=1).Subtitle("Spinner Q=1 " + String(y) + " to " + String(z),align=5)
last + a.Spinner(angle=x,eangle=y,check=false,bg=false,q=0).Subtitle("Spinner Q=0 " + String(x) + " to " + String(y),align=5)
last + a.Spinner(angle=y,eangle=z,check=false,bg=false,q=0).Subtitle("Spinner Q=0 " + String(y) + " to " + String(z),align=5)
Function Angle(clip c, float a, int mode)
{
b = (Round(abs(a)*1000)%360000)/1000.0
d = a < 0 ? 1-(b/360.0) : b/360.0
b = a < 0 ? -b : b
c
mode == 0 ? Subtitle("Orginal (no rotation) " + String(a),align=5) :
\ mode == 1 ? Zoom(angle=string(a)).Subtitle("Zoom " + String(a),align=5) :
\ mode == 2 ? Freeframe("C:\Program Files\AviSynth 2.5\plugins\PetePanSpinZoom.dll",false,0.5,0.5,d,0.2).Subtitle("PetePanSpinZoom " + String(d),align=5) :
\ mode == 3 ? EffectRotation(id=-a, cc=$000000).Subtitle("EffectRotation " + String(-a),align=5) :
\ mode == 4 ? Rotate(a).Subtitle("Rotate " + String(a),align=5) :
\ mode == 5 ? Spinner(angle=a,check=false,bg=false,q=2).Subtitle("Spinner Q=2 " + String(a),align=5) :
\ mode == 6 ? Spinner(angle=a,check=false,bg=false,q=1).Subtitle("Spinner Q=1 " + String(a),align=5) :
\ Spinner(angle=a,check=false,bg=false,q=0).Subtitle("Spinner Q=0 " + String(a),align=5)
}
Rotate's built in rotation function seems to not exist.
Everything else works great!
Speed
None: 28fps
Rotate: 17fps - Disqualified though...
Spinner Q=0: 17fps
FreeFrame: 16fps
Zoom: 8fps
Spinner Q=1: 6fps
EffectRotation: 6fps
Spinner Q=2: 2fps
Gavino
6th August 2008, 11:16
Zoom(angle="spline(n, " + String(0) + "," + String(x) + ", " + \
String(a.framecount()-1) + "," + String(y) + ", false)", show=true)
# ... [reformatted to fit]
Note that if x, y and a are script-level variables (as they are here), you can simply write
Zoom(angle="spline(n, 0, x, a.framecount()-1, y, false)", show=true)
I doubt if it will be any faster, but it's certainly easier to read.
The use of show=true could affect the speed though.
vcmohan
10th August 2008, 13:02
I have modified the code extensively. Now Spinner accepts YUY2 format also. A new parameter p is added with which one can specify the location accuracy. (1/4 pixel to 1/5000) pixel. For quality Lagrange and Lanczos interpolation are now available. Both have 4 and 6 point options.
I got hold of Rotate plugin from warpenterprises site. Oct 2007 dated. I did some comparison of quality. The script used is :
im1 = imagereader("E:\images\canyon.jpg", end = 361).converttoRGB32()
im1 = reduceby2(im1)
a = 2
b= 60
c= 120
d= 400
e = 1000
s0 = Spinner(im1,q = a, angle = b, eangle = c, check = false, p =d, bg = false, color = 0)
s1 = Spinner(s0,q = a, angle = b, eangle = c, check = false, p =d, bg = false, color = 0)
s2 = Spinner(s1,q = a, angle = b, eangle = c, check = false, p =d, bg = false, color = 0)
s3 = Spinner(s2,q = a, angle = b, eangle = c, check = false, p =d, bg = false, color = 0)
s4 = Spinner(s3,q = a, angle = b, eangle = c, check = false, p =d, bg = false, color = 0)
s5 = Spinner(s4,q = a, angle = b, eangle = c, check = false, p =d, bg = false, color = 0)
rt0= Rotate(im1,angle = b)
rt1= Rotate(rt0,angle = b)
rt2= Rotate(rt1,angle = b)
rt3= Rotate(rt2,angle = b)
rt4= Rotate(rt3,angle = b)
rt5= Rotate(rt4,angle = b)
sb1=Subtract(s5,im1).Levels(127,1,129,0,255)
sb2=Subtract(rt5,im1).Levels(127,1,129,0,255)
sh1 = stackhorizontal(s5,sb1)
sh2 = stackhorizontal(rt5,sb2)
stackvertical(sh1,sh2)
The above code rotates image by 60 degrees 6 times to get back initial image.
The result is as below. On top row left is Spinner output with Lagrange 4 point interpolation, on its right is subtract from original. Bottom row is corresponding Rotate output.
http://img230.imageshack.us/img230/8081/spinnercomp0jj2.th.jpg (http://img230.imageshack.us/my.php?image=spinnercomp0jj2.jpg)
Even for lowest quality q = 0, IMO Spinner appears far superior.
I request mikeytown2 to do a speed test again. As there are initial overheads for the first frame, animate may not give correct speed measurement. Probably over 1000 or more frames in a run to be measured. Lanczos 6 pt (q = 5) should give better results.
mikeytown2
10th August 2008, 22:37
Here is a quality test code block. Thanks vcmohan for inspiring this.
ImageReader("wikipediamiamisunset200ke5.jpg")
ColorBars()
lr=130
tb=210
im1=last.ConvertToRGB32().BicubicResize(640,480).AddBorders(lr,tb,lr,tb).Trim(0,-1)
a= 2
b= 60
c= 60
d= 5000
lr=lr
tb=tb
Spinner(im1,q = a, angle = b, eangle = c, check = false, p =d, bg = false, color = 0)
Spinner(q = a, angle = b, eangle = c, check = false, p =d, bg = false, color = 0)
Spinner(q = a, angle = b, eangle = c, check = false, p =d, bg = false, color = 0)
Spinner(q = a, angle = b, eangle = c, check = false, p =d, bg = false, color = 0)
Spinner(q = a, angle = b, eangle = c, check = false, p =d, bg = false, color = 0)
s5 = Spinner(q = a, angle = b, eangle = c, check = false, p =d, bg = false, color = 0).Crop(lr,tb,-lr,-tb)
Rotate(im1,angle = b)
Rotate(angle = b)
Rotate(angle = b)
Rotate(angle = b)
Rotate(angle = b)
rt5= Rotate(angle = b).Crop(lr,tb,-lr,-tb)
Function StackComparer(clip x, clip y, string s)
{
sb1=Subtract(x,y)
sb1=Overlay(sb1.Levels(128,1,130,0,255),
\ sb1.Levels(126,1,128,0,255).PointResize(640*4,480*4).ConvertToYUY2().Invert("y").ConvertToRGB32().PointResize(640,480)
\ ,mode="add").Levels(23,1,255,0,255).Subtitle("Black pixels means less/no change")
s5=Compare(x,y).Subtitle(String(s), Align=4)
stackhorizontal(s5,BlankClip(1,1,480,color=$FFFFFF),BlankClip(1,1,480,color=$000000),BlankClip(1,1,480,color=$FFFFFF),sb1)
}
sh1=StackComparer(s5,im1.Crop(lr,tb,-lr,-tb),"Spinner Q=" + String(a) + " P=" + String(d))
sh2=StackComparer(rt5,im1.Crop(lr,tb,-lr,-tb),"Rotate")
sh3=StackComparer(im1.Crop(lr,tb,-lr,-tb),im1.Crop(lr,tb,-lr,-tb),"Orginal")
stackvertical(sh1,BlankClip(1,1283,1,color=$FFFFFF),BlankClip(1,1283,1,color=$000000),BlankClip(1,1283,1,color=$FFFFFF),sh2
\ ,BlankClip(1,1283,1,color=$FFFFFF),BlankClip(1,1283,1,color=$000000),BlankClip(1,1283,1,color=$FFFFFF),sh3)
Output
http://img204.imageshack.us/img204/305/angleszj5.th.png (http://img204.imageshack.us/my.php?image=angleszj5.png)
http://img212.imageshack.us/img212/4370/angleszb7.th.jpg (http://img212.imageshack.us/my.php?image=angleszb7.jpg)
image from wikipedia (http://en.wikipedia.org/wiki/Sunset)
http://img440.imageshack.us/img440/7429/wikipediamiamisunset200ke5.th.jpg (http://img440.imageshack.us/my.php?image=wikipediamiamisunset200ke5.jpg)
In my previous comparisons I was looking at the aliasing, it appears that Rotate() has built in AA, which is why I preferred it in my previous post. When using Rotate() multiple times AA hurts the final output. So in terms of Quality (PSNR) Spinner wins, but there are some issues. It doesn't handle solid colors correctly as you can see with the ColorBars() test when P is set above 16. Also if it had an Edge AA option that would be nice feature.
Here is a speed test between Rotate and Spinner
a = ColorBars(1024,768).Trim(0,999)
x=-500.0*20
y=510.0
z=520.0
a.trim(0,-1)
Animate(0, a.framecount()-1, "Angle", a, float(x), 0, a, float(y), 0)
last + Animate(0, a.framecount()-1, "Angle", a, float(y), 0, a, float(z), 0)
last + Animate(0, a.framecount()-1, "Angle", a, float(x), 4, a, float(y), 4)
last + Animate(0, a.framecount()-1, "Angle", a, float(y), 4, a, float(z), 4)
last + a.Spinner(angle=x,eangle=y,check=false,bg=false,q=2,p=5000).Subtitle("Spinner Q=2 P=5000 " + String(x) + " to " + String(y),align=5)
last + a.Spinner(angle=y,eangle=z,check=false,bg=false,q=2,p=5000).Subtitle("Spinner Q=2 P=5000 " + String(y) + " to " + String(z),align=5)
last + a.Spinner(angle=x,eangle=y,check=false,bg=false,q=2,p=4).Subtitle("Spinner Q=2 P=4 " + String(x) + " to " + String(y),align=5)
last + a.Spinner(angle=y,eangle=z,check=false,bg=false,q=2,p=4).Subtitle("Spinner Q=2 P=4 " + String(y) + " to " + String(z),align=5)
last + a.Spinner(angle=x,eangle=y,check=false,bg=false,q=1,p=5000).Subtitle("Spinner Q=1 P=5000 " + String(x) + " to " + String(y),align=5)
last + a.Spinner(angle=y,eangle=z,check=false,bg=false,q=1,p=5000).Subtitle("Spinner Q=1 P=5000 " + String(y) + " to " + String(z),align=5)
last + a.Spinner(angle=x,eangle=y,check=false,bg=false,q=1,p=4).Subtitle("Spinner Q=1 P=4 " + String(x) + " to " + String(y),align=5)
last + a.Spinner(angle=y,eangle=z,check=false,bg=false,q=1,p=4).Subtitle("Spinner Q=1 P=4 " + String(y) + " to " + String(z),align=5)
last + a.Spinner(angle=x,eangle=y,check=false,bg=false,q=0,p=5000).Subtitle("Spinner Q=0 P=5000 " + String(x) + " to " + String(y),align=5)
last + a.Spinner(angle=y,eangle=z,check=false,bg=false,q=0,p=5000).Subtitle("Spinner Q=0 P=5000 " + String(y) + " to " + String(z),align=5)
last + a.Spinner(angle=x,eangle=y,check=false,bg=false,q=0,p=4).Subtitle("Spinner Q=0 P=4 " + String(x) + " to " + String(y),align=5)
last + a.Spinner(angle=y,eangle=z,check=false,bg=false,q=0,p=4).Subtitle("Spinner Q=0 P=4 " + String(y) + " to " + String(z),align=5)
Function Angle(clip c, float a, int mode)
{
b = (Round(abs(a)*1000)%360000)/1000.0
d = a < 0 ? 1-(b/360.0) : b/360.0
b = a < 0 ? -b : b
c
mode == 0 ? Subtitle("Orginal (no rotation) " + String(a),align=5) :
\ mode == 1 ? Zoom(angle=string(a)).Subtitle("Zoom " + String(a),align=5) :
\ mode == 2 ? Freeframe("C:\Program Files\AviSynth 2.5\plugins\PetePanSpinZoom.dll",false,0.5,0.5,d,0.2).Subtitle("PetePanSpinZoom " + String(d),align=5) :
\ mode == 3 ? EffectRotation(id=-a, cc=$000000).Subtitle("EffectRotation " + String(-a),align=5) :
\ mode == 4 ? Rotate(a).Subtitle("Rotate " + String(a),align=5) :
\ mode == 5 ? Spinner(angle=a,check=false,bg=false,q=2).Subtitle("Spinner Q=2 " + String(a),align=5) :
\ mode == 6 ? Spinner(angle=a,check=false,bg=false,q=1).Subtitle("Spinner Q=1 " + String(a),align=5) :
\ Spinner(angle=a,check=false,bg=false,q=0).Subtitle("Spinner Q=0 " + String(a),align=5)
}
Method: Only use one line at a time, load in Vdub, Click input playback, go view -> show status window, un-check show input video, watch FPS.
Results:
None: 28.0fps
Rotate:
13.65 - Big Angle
13.00 - Small Angle
Spinner:
5.35 - BA,q=2,p=5k
5.30 - SA,q=2,p=5k
5.45 - BA,q=2,p=4
5.40 - SA,q=2,p=4
9.80 - BA,q=1,p=5k
9.85 - SA,q=1,p=5k
10.0 - BA,q=1,p=4
9.95 - SA,q=1,p=4
15.20 - BA,q=0,p=5k
15.35 - SA,q=0,p=5k
16.16 - BA,q=0,p=4
16.30 - SA,q=0,p=4
vcmohan
11th August 2008, 13:13
Thanks for the effort. On seeing the color bars comparison I could locate the source for this error. I now corrected it. The quality should improve further.
As for speed. I just tried the
colorbars()
and got on my system very near 30fps. When I added the lines
cb = ColorBars().Trim(0,9999)
a=2
b= 60
c= 420
d= 400
e = 1000
s0 = Spinner(cb,q = 1,x = -100, ex = 600, angle = b, eangle = c, check = false, p =d, bg = false, color = 0)
return(s0)
Strangely I got fps varying from 40 to 32.
Something is not right. Using vdub rendering fps may not correctly indicate speed. I recollect some plugin timer or some such named. Possibly it does a better estimate.
mikeytown2
11th August 2008, 19:37
Using Spinner.dll with timestamp of August 11, 2008, 5:12:00 PM, with my above code slightly modified here is output with p=16 and p=17
http://img204.imageshack.us/img204/7109/anglesgc6.th.png (http://img204.imageshack.us/my.php?image=anglesgc6.png)
I'll look into other FPS measurement methods. Just a heads up, I used ColorBars(1024,768) with the speed test.
vcmohan
12th August 2008, 03:30
Thanks for the test. The parameter p has very insignificant effect on the speed of processing. It was only provided for sake of 'effects' if some one needs. As such one may not use lower values if one needs quality. It however calls for higher requirement of memory. For example at p = 5000 and q = 3 or 5 , it requires an additional 240kb( present day standards negligible) while at p=16, q = 1 it just needs 128 bytes extra.
Therefore pl test for quality with p as high as possible. Similarly q =3 or 5 gives higher quality. Ofcourse they are the slowest. One needs to make conscious compromises.
I have checked with q = 1, in the manner I did earlier and compared with Rotation plugin. In this mode it is bilinear interpolation, which is also used by Rotation and so spinner should give comparable quality to that of Rotation. Even here Spinner output looks better than that of Rotation. May be Fizick can comment on this.
mikeytown2
15th August 2008, 20:38
I got the latest aug 14th version
p=100 for all the below results
q=0, q=1, q=2 work as expected, good job!
q=3 & q=5 are off with my colorbars test
q=4 needs some help
Run the first code block from post 17 (http://forum.doom9.org/showthread.php?p=1169108#post1169108) in AvsP. With q=0-2 the solid colors stay solid. with q=3-5 they are no longer solid! put your mouse over the preview and look at the color hex values in the lower left. q=3 gives the highest PSNR but because of the solid color instability this is lower then it could be!
vcmohan
17th August 2008, 04:44
@mickeytown2
I have corrected a floating point rounding off error. It should work well now. Pl check once again. Sorry for the trouble
mikeytown2
17th August 2008, 08:53
@vcmohan
Nice work! Your RGB spinner is very good! I'm still playing around with MVtools, so in a day or 2 i'll post some speed comparisons.
mikeytown2
20th August 2008, 06:09
Code Used:
a = ColorBars(1024,768).Trim(0,199)
x=-500.0*2
y=510.0
z=520.0
a.trim(0,-1)
last + a.Spinner(angle=x,eangle=y,check=false,bg=false,q=5,p=100).Subtitle("Spinner Q=5 p=100 " + String(x) + " to " + String(y),align=5)
last + a.Spinner(angle=y,eangle=z,check=false,bg=false,q=5,p=100).Subtitle("Spinner Q=5 p=100 " + String(y) + " to " + String(z),align=5)
last + a.Spinner(angle=x,eangle=y,check=false,bg=false,q=5,p=5).Subtitle("Spinner Q=5 p=5 " + String(x) + " to " + String(y),align=5)
last + a.Spinner(angle=y,eangle=z,check=false,bg=false,q=5,p=5).Subtitle("Spinner Q=5 p=5 " + String(y) + " to " + String(z),align=5)
last + a.Spinner(angle=x,eangle=y,check=false,bg=false,q=4,p=100).Subtitle("Spinner Q=4 p=100 " + String(x) + " to " + String(y),align=5)
last + a.Spinner(angle=y,eangle=z,check=false,bg=false,q=4,p=100).Subtitle("Spinner Q=4 p=100 " + String(y) + " to " + String(z),align=5)
last + a.Spinner(angle=x,eangle=y,check=false,bg=false,q=4,p=5).Subtitle("Spinner Q=4 p=5 " + String(x) + " to " + String(y),align=5)
last + a.Spinner(angle=y,eangle=z,check=false,bg=false,q=4,p=5).Subtitle("Spinner Q=4 p=5 " + String(y) + " to " + String(z),align=5)
last + a.Spinner(angle=x,eangle=y,check=false,bg=false,q=3,p=100).Subtitle("Spinner Q=3 p=100 " + String(x) + " to " + String(y),align=5)
last + a.Spinner(angle=y,eangle=z,check=false,bg=false,q=3,p=100).Subtitle("Spinner Q=3 p=100 " + String(y) + " to " + String(z),align=5)
last + a.Spinner(angle=x,eangle=y,check=false,bg=false,q=3,p=5).Subtitle("Spinner Q=3 p=5 " + String(x) + " to " + String(y),align=5)
last + a.Spinner(angle=y,eangle=z,check=false,bg=false,q=3,p=5).Subtitle("Spinner Q=3 p=5 " + String(y) + " to " + String(z),align=5)
last + a.Spinner(angle=x,eangle=y,check=false,bg=false,q=2,p=100).Subtitle("Spinner Q=2 p=100 " + String(x) + " to " + String(y),align=5)
last + a.Spinner(angle=y,eangle=z,check=false,bg=false,q=2,p=100).Subtitle("Spinner Q=2 p=100 " + String(y) + " to " + String(z),align=5)
last + a.Spinner(angle=x,eangle=y,check=false,bg=false,q=2,p=5).Subtitle("Spinner Q=2 p=5 " + String(x) + " to " + String(y),align=5)
last + a.Spinner(angle=y,eangle=z,check=false,bg=false,q=2,p=5).Subtitle("Spinner Q=2 p=5 " + String(y) + " to " + String(z),align=5)
last + a.Spinner(angle=x,eangle=y,check=false,bg=false,q=1,p=100).Subtitle("Spinner Q=1 p=100 " + String(x) + " to " + String(y),align=5)
last + a.Spinner(angle=y,eangle=z,check=false,bg=false,q=1,p=100).Subtitle("Spinner Q=1 p=100 " + String(y) + " to " + String(z),align=5)
last + a.Spinner(angle=x,eangle=y,check=false,bg=false,q=1,p=5).Subtitle("Spinner Q=1 p=5 " + String(x) + " to " + String(y),align=5)
last + a.Spinner(angle=y,eangle=z,check=false,bg=false,q=1,p=5).Subtitle("Spinner Q=1 p=5 " + String(y) + " to " + String(z),align=5)
last + a.Spinner(angle=x,eangle=y,check=false,bg=false,q=0,p=100).Subtitle("Spinner Q=0 p=100 " + String(x) + " to " + String(y),align=5)
last + a.Spinner(angle=y,eangle=z,check=false,bg=false,q=0,p=100).Subtitle("Spinner Q=0 p=100 " + String(y) + " to " + String(z),align=5)
last + a.Spinner(angle=x,eangle=y,check=false,bg=false,q=0,p=5).Subtitle("Spinner Q=0 p=5 " + String(x) + " to " + String(y),align=5)
last + a.Spinner(angle=y,eangle=z,check=false,bg=false,q=0,p=5).Subtitle("Spinner Q=0 p=5 " + String(y) + " to " + String(z),align=5)
last + Animate(0, a.framecount()-1, "Angle", a, float(x), 0, a, float(y), 0)
last + Animate(0, a.framecount()-1, "Angle", a, float(y), 0, a, float(z), 0)
last + Animate(0, a.framecount()-1, "Angle", a, float(x), 4, a, float(y), 4)
last + Animate(0, a.framecount()-1, "Angle", a, float(y), 4, a, float(z), 4)
Function Angle(clip c, float a, int mode)
{
b = (Round(abs(a)*1000)%360000)/1000.0
d = a < 0 ? 1-(b/360.0) : b/360.0
b = a < 0 ? -b : b
c
mode == 0 ? Subtitle("Orginal (no rotation) " + String(a),align=5) :
\ mode == 1 ? Zoom(angle=string(a)).Subtitle("Zoom " + String(a),align=5) :
\ mode == 2 ? Freeframe("C:\Program Files\AviSynth 2.5\plugins\PetePanSpinZoom.dll",false,0.5,0.5,d,0.2).Subtitle("PetePanSpinZoom " + String(d),align=5) :
\ mode == 3 ? EffectRotation(id=-a, cc=$000000).Subtitle("EffectRotation " + String(-a),align=5) :
\ mode == 4 ? Rotate(a).Subtitle("Rotate " + String(a),align=5) :
\ mode == 5 ? Spinner(angle=a,check=false,bg=false,q=2).Subtitle("Spinner Q=2 " + String(a),align=5) :
\ mode == 6 ? Spinner(angle=a,check=false,bg=false,q=1).Subtitle("Spinner Q=1 " + String(a),align=5) :
\ Spinner(angle=a,check=false,bg=false,q=0).Subtitle("Spinner Q=0 " + String(a),align=5)
}
Put it inside MeGui with the x264 defaults and ran the analysis pass only.
Results:
Set Big Small
None 31.2
5,100 2.9, 2.9
5,5 2.9, 2.9
4,100 4.6, 4.4
4,5 4.65, 4.65
3,100 2.9, 2.85
3,5 2.95, 2.9
2,100 4.65, 4.6
2,5 4.7, 4.65
1,100 7.7, 7.6
1,5 7.8, 7.7
0,100 9.9, 9.9
0,5 9.95, 9.9
Rotate 13.5, 14.2
One thing I do notice is your code seems to never use more then 55% where the rotate will use around 75% and None uses 70% of my cpu's.
I did a quick check and Vdub's results are about the same as well.
vcmohan
20th August 2008, 10:13
Thanks for the test.
Rotate and Spinner for q =1 mode use bilinear interpolation and so comparable in performance. Rotate is twice as fast but somewhat poorer in quality. Other values for Q of Spinner output has much higher quality.
tin3tin
4th September 2008, 09:03
Very nice plugin. I'm trying to make some transitions with it. :)
Would it be possible to add an option to make the background another clip than the input clip?
Ex: at = colorbars().trim(1,25)
bt = colorbars().trim(1,25).invert()
Spinner(at,q = 0, x=int(at.width()),y=int(at.height()),angle = 0, eangle = 90,check=false)
So 'at' rotates out of frame and reveals 'bt'?
The workaround(which eats up some speed I guess):
loadplugin("Spinner.dll")
ft=25
at = colorbars().trim(1,ft)
bt = colorbars().trim(1,ft).invert()
at=Spinner(at,q = 0, x=int(at.width()),y=int(at.height()),angle = 0, eangle = 90,check=false,color=00000000,bg=false)
maskclip=Mask(at, at.GreyScale.Levels( 0, 0.001, 0, 0, 255))
overlay(bt,at,x=0,y=0,mask=showalpha(maskclip),opacity=1.0,mode="blend")
vcmohan
4th September 2008, 10:45
In the transall plugin a function TransSwing may be the one you need. Please check up and if it does not suit then I can think of adding this. As in a transition very high quality is not needed, it uses equivalent to q =0 of spinner.
tin3tin
4th September 2008, 11:20
Yes, you're right TransSwing can do that speciffic transition I coded above(forgot about that one).
However I still think it would be useful with an optional alternative clip as background for the spinner plugin.
There are more ways to rotate a clip out of the frame to reveal another clip. :)
[EDIT: Here's an example of using the transition above in DVD slideshow GUI: Rotate Transitions (http://download.videohelp.com/tin2tin/RotateTransitions.html)]
mikeytown2
4th September 2008, 11:22
vcmohan
adding a mask/alpha channel when RGB32() wouldn't be a bad idea. It would get rid of this ugliness; it would also open up some doors for anti aliasing the edge.
maskclip=Mask(at, at.GreyScale.Levels( 0, 0.001, 0, 0, 255))
Also there's an alignment problem with tin3tin's example on the far right. showalpha(maskclip) at frame 0 is when the problem is clearly visible.
vcmohan
5th September 2008, 12:27
However I still think it would be useful with an optional alternative clip as background for the spinner plugin. [/URL]]
OK. I just added a parameter "tclip" which if specified and "bg" is true will use this tclip frames as background.
@mikeytown2
mask/anlpha channel in RGB32
I can do that. But do I need to interpolate that channel also and to same accuracy?
tin3tin
5th September 2008, 13:21
Thank you very much! :thanks:
mikeytown2
5th September 2008, 19:44
@vcmohan
No need, I can use tclip, example below
a = ImageReader("wikipediamiamisunset200ke5.jpg",pixel_type="RGB32").Trim(0,99)
b = ColorBars().Trim(0,99)
a.Spinner(angle=0,eangle=90,tclip=b,p=100,check = false)
edge_mask=ShowAlpha().ConvertToYV12().mt_edge(mode="laplace").Grayscale().ConvertToRGB32()
Overlay(last,Blur(1.58),mask=edge_mask)
mikeytown2
5th September 2008, 20:28
Did some testing, and there are some quality issues. Run the code below and you should see what I'm talking about. tclip seems to change the colors slightly; 90 is not straight up and down; stray pixels on the far right edge.
a = ImageReader("wikipediamiamisunset200ke5.jpg",pixel_type="RGB32").Trim(0,99)
b = ColorBars().Trim(0,99)
#~ b = BlankClip()
x=a.Spinner(angle=90,eangle=90,tclip=b,p=100,check = false,q=5)
a.TurnRight().Crop(0,80,0,-80)
y=Overlay(b,last,80)
#~ StackHorizontal(x,y)
StackComparer(x,y,"")
Function StackComparer(clip x, clip y, string s)
{
sb1=Subtract(y,x)
sb1=Overlay(sb1.Levels(128,1,130,0,255),
\ sb1.Levels(126,1,128,0,255).PointResize(640*4,480*4).ConvertToYUY2().Invert("y").ConvertToRGB32().PointResize(640,480)
\ ,mode="add").Levels(23,1,255,0,255).Subtitle("Black pixels means less/no change")
s5=Compare(x,y).Subtitle(String(s), Align=4)
stackhorizontal(s5,sb1)
}
This is starting to look very promising, keep up the good work!
vcmohan
6th September 2008, 13:35
tclip seems to change the colors slightly; 90 is not straight up and down; stray pixels on the far right edge.
Yes. I have seen. Infact it is more near to vertical for angle of 89.98 or so. It appears this error is due to use of float. The axis coordinates are in float, the angle also in float. The inaccuracy is sum of all the floating point operations. Double precision can be used but it further slows down. Since the background is colorbars possibly it can also be rotated by same angle and used to check.
mikeytown2
3rd October 2008, 20:51
Here is a much better but slower AA rotate code block
a = ImageReader("wikipediamiamisunset200ke5.jpg",pixel_type="RGB32").Trim(0,99)
b = ColorBars(width(a),height(a)).Trim(0,99)
SS = 2.2
x = a.Spinner(angle=0,eangle=90,tclip=b,p=100,check = false)
y = a.BilinearResize(Round(width(a)*SS),Round(height(a)*SS))
y = y.Spinner(angle=0,eangle=90,tclip=b.BilinearResize(Round(width(a)*SS),Round(height(a)*SS)),p=100,check = false)
y = y.BilinearResize(width(a),height(a))
edge_mask=x.ShowAlpha().ConvertToYV12().mt_edge(mode="laplace").Grayscale().ConvertToRGB32().Blur(1.58).Levels(0,1,128,0,255)
Overlay(x,y,mask=edge_mask)
Any chance of optimizing this somehow?
vcmohan
4th October 2008, 10:21
What is mt_edge ? I get an error about this.
mikeytown2
4th October 2008, 10:22
Function in MaskTools2
http://manao4.free.fr/masktools-v2.0a35.zip
http://avisynth.org/mediawiki/MaskTools2/Mt_edge
vcmohan
5th October 2008, 03:35
Do you mean speeding up by 'optimising' ? If so Since you are increasing the size by 2.2 X 2.2 times both clips and then rotating them it will run very very slow. Most of the time in the Spinner is spent in the LaQuant module. If some kind soul codes that in assembly I will be grateful.
mikeytown2
5th October 2008, 10:54
In terms of the number of pixels that need to be multiplied, it's a small amount. I was wondering if you could blow up the edge pixels, rotate them, then scale them back down; all inside your plugin. It produces a better looking edge, even though it may not be mathematically correct.
Here's the above code, Also with Full Screen Anti Aliasing for the rotated object. I also made the alpha channel instead of assuming the best. Using q=1 & p=5 helps out. FSAA is a little overkill but it's an example of what should stay outside of the plugin, if you were to incorporate AA for the edge somehow.
a = ImageReader("wikipediamiamisunset200ke5.jpg",pixel_type="RGB32").Trim(0,99).ResetMask()
b = ColorBars(width(a),height(a)).Trim(0,99).ResetMask()
b = b.Mask(b.ShowAlpha().Invert())
SS = 2.2
x = a.Spinner(angle=0,eangle=90,tclip=b,p=100,check = false)
y = a.Spline16Resize(Round(width(a)*SS),Round(height(a)*SS))
y = y.Spinner(angle=0,eangle=90,tclip=b.BilinearResize(Round(width(a)*SS),Round(height(a)*SS)),check = false,q=1,p=5)
y = y.Spline16Resize(width(a),height(a))
edge_mask=x.ShowAlpha().ConvertToYV12().mt_edge(mode="laplace").Grayscale().ConvertToRGB32().Blur(1.58).Levels(0,1,128,0,255)
fsaa_mask=Overlay(x,BlankClip(),mask=x.ShowAlpha().Invert()).ConvertToYV12().mt_edge(mode="laplace").Grayscale().ConvertToRGB32().Blur(1.58).Levels(86,1,192,0,255)
Overlay(x,y,mask=edge_mask)
Overlay(last,y,mask=fsaa_mask)
vcmohan
6th October 2008, 02:59
Thanks for the suggestion. I do not understand what exactly is happenning in the AA script. The show alpha and overlay writeup I am unable to understand, possibly since I have not used them.
If what is done inside then I can possibly code it.
As the edge nears, since there are fewer pixels than required for interpolation then in case of q = 5 or 3, from 6 taps it is decreased to 4 taps then to bilinear. So the edges do suffer.
mikeytown2
6th October 2008, 03:23
Frame 33
I use the Alpha channel in order to differentiate between the background and the foreground. That is what the Invert() is for on line 3.
http://img374.imageshack.us/img374/6035/alphasy3.th.jpg (http://img374.imageshack.us/my.php?image=alphasy3.jpg)http://img374.imageshack.us/images/thpix.gif (http://g.imageshack.us/thpix.php)
No AA, like usual
http://img526.imageshack.us/img526/8618/noaagt6.th.jpg (http://img526.imageshack.us/my.php?image=noaagt6.jpg)
2.2 Supersampled (http://en.wikipedia.org/wiki/Supersampling); gives blurry results in the middle of the image even when q=5; for this i use q=1 because of speed
http://img232.imageshack.us/img232/8775/aa1qu3.th.jpg (http://img232.imageshack.us/my.php?image=aa1qu3.jpg)
Supersampled on border edge only
http://img135.imageshack.us/img135/1286/aa2vh3.th.jpg (http://img135.imageshack.us/my.php?image=aa2vh3.jpg)
http://img80.imageshack.us/img80/6930/edgemaskwp3.th.jpg (http://img80.imageshack.us/my.php?image=edgemaskwp3.jpg)
Supersampled on border edge and edges in the pix (FSAA)
http://img184.imageshack.us/img184/1484/aa3jk4.th.jpg (http://img184.imageshack.us/my.php?image=aa3jk4.jpg)
http://img513.imageshack.us/img513/2010/bothaamasksru3.th.jpg (http://img513.imageshack.us/my.php?image=bothaamasksru3.jpg)
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.