Log in

View Full Version : MVTool2 and large Zooms


jmac698
28th December 2010, 14:01
Why doesn't mvtools work with a zoom>1.2?
Update: added DePan, it's not working either..., used Didee's suggestion

#Find a square clip in arectangle clip, put on top of rectangle, using MVTools2 or DePan to do image registration
#requires mvtool2 and depan
#In the demo you will see an inset; this is the square.
#In the upper left, in white, you see what the script found by analyzing the video. Sometimes it doesn't work, that's what this script is here to find out!
#To use: set dir and MPEG2SOURCe below to pick any widescreen video you have
#then view frame 0, and step through to frame 20.
#first you will see dx move smoothly from 280 to -280, then you will see zoom change from 1 to 1.15, then it FAILS! (look at frame 523, 524)
#method2 isn't working either
#Use any 2.35:1, anamorphic DVD video you have here:
dir="C:\movies\process\Enough-ws\MainMovie\Enough\VIDEO_TS\"
ws=MPEG2Source(dir+"Enough-ws.d2v").crop(0,56,0,-60).Telecide(guide=1).trim(500,0)#crop out the anamorphic/letterbox borders, skip ahead toa free that's not black/titles
newx=int(2.35*480)#stretch anamorphic video (non-standard pixel aspect which I suspect is being used anyway!)
newx=1280#There's a bug somewhere?
ws=ws.bilinearresize(newx,480)#This is a bit oversized, but I want to show case of square.height=480
#create demo video
shiftx=0#x<0 is left, dx from MDpan will be opposite to undo it
shifty=0#y<0 is down, dy will have opposite sign
zoom=1
aspect=1#zx/zy
kenburns="zoomshift"
startframe=0
#Sequence 1, pan left
panspeed=28
sxstart=280#maximum right side pan
len=20#in frames, does a maximum pan
sxend=sxstart-(len-1)*panspeed
endframe=startframe+len-1
animate(ws,startframe,endframe,kenburns,zoom*aspect,zoom,sxstart,0,1,zoom*aspect,zoom,sxend,0,1)
startframe=endframe+1
#Sequence 2, zoom in
zoomspeed=.05
zstart=1
len=10#in frames
zend=zstart+(len-1)*zoomspeed
endframe=startframe+len-1
animate(startframe,endframe,kenburns,zstart*aspect,zstart,0,0,1,zend*aspect,zend,0,0,1)
global fs=last.aspectconvert(ws.width,ws.height)#what I call full screen; the square within the widescreen rectangle, it's what we just made
#we need aspectconvert to match widths so we can use interleave
interleave(fs,ws)#Trick to make mvtools compare two videos
global source=last
detectionmethod=0#0 for mvtools2, 1 for depanestimate
select(detectionmethod,method1,method2)
function method1(clip v) {
v
super = MSuper(source)
size=4
p=4#step
r=280#radius
#Note: resulting transform can be dx=+-280, dy=+-16, zoom=1 to 1.33
vectors=MAnalyse(super, isb = false,temporal=false,blksize=size)
v1=MAnalyse(super, isb = false,search=0,searchparam=p,temporal=false,blksize=size).common
v2=MAnalyse(super, isb = false,search=1,searchparam=p,temporal=false,blksize=size).common
v3=MAnalyse(super, isb = false,search=2,searchparam=p,temporal=false,blksize=size).common
v4=MAnalyse(super, isb = false,search=3,searchparam=r,temporal=false,blksize=size).common
v5=MAnalyse(super, isb = false,search=4,searchparam=p,temporal=false,blksize=size).common
v6=MAnalyse(super, isb = false,search=5,searchparam=p,temporal=false,blksize=size).common
#try various search algorithms at once
comparemethods=false
(comparemethods==false)?MDepan(source,vectors,zoom=true,rot=false,info=true).selectevery(2,1).overlay(fs.pointresize(1280/2,480/2),y=240) \
:stackvertical(v1,v2,v3,v4,v5,v6).selectevery(2,1)
}

function method2(clip v) {
v
globalmotion=DePanEstimate (zoommax=1.4, improve=false, info=true, fftw=true,range=2)
DePan(v,globalmotion,info=true).selectevery(2,1).overlay(fs.pointresize(1280/2,480/2),y=240)
return globalmotion.selectevery(2,1)
}

function common(clip v) {
MDepan(source,v,zoom=true,rot=false,info=true)
Crop(0, 20, -960, -380)#Show MVDepan data only
}

function zoomshift(clip v,float zx,float zy,int sx,int sy,int "info") {
info=default(info,0)#can't use this when zoomshift is called more than once
finalw=720#shift, zoom, panscan
finalh=480
shift(v,sx,sy)
zoom(zx,zy)
aspectconvert(finalw,finalh)
}

function shift(clip v, int sx, int sy) {
v#shift a video sx, sy pixels, sx<0 is left, sy<0 is down
pointresize(width*2,height*2)#to allow 1 pixel shifts in YV12
sx=sx*2
sy=sy*2
l=(sx<0)?-sx:0
r=(sx<0)?0:sx
t=(sy<0)?0:sy
b=(sy<0)?-sy:0
crop(l,t,-r,-b)
addborders(r,b,l,t)
bilinearresize(v.width,v.height)
}

function zoom(clip v, float zx, float zy) {
v#Zoom but cropping to original size
pointresize(width*2,height*2)#to allow 1 pixel increments in YV12
w=int(zx*width/4+.5)*4
h=int(zy*height/4+.5)*4
addleft=(zx<1)?(width-w)/2:0
addtop=(zy<1)?(height-h)/2:0
bilinearresize(w,h)#zoom
left=(zx>1)?int((w-v.width*2)/2):0
top=(zy>1)?int((h-v.height*2)/2):0
crop(left,top,-left,-top)#Keep only centered portion of zoomed video
addborders(addleft,addtop,addleft,addtop)
bilinearresize(width/2,height/2)#back to normal size
}

function aspectconvert(clip v, int w, int h) {
v#Extract a wxh video from original, e.g. a square cut out of a rectangle, centered
#If source is smaller than dest, center source in dest
#If source is less wide than dest, center crop source (i.e. pan scan)
#If source is taller than dest, center crop source
#a square (dest) on a widescreen (in) does a center cut. A widescreen on a square does a letterbox.
pointresize(width*2,height*2)
w=w*2
h=h*2
left=(w<width)?(width-w)/2:0
addleft=(w>width)?(w-width)/2:0
top=(h<height)?(height-h)/2:0
addtop=(h>height)?(h-height)/2:0
addborders(addleft,addtop,addleft,addtop)
crop(left,top,-left,-top)
pointresize(w/2,h/2)
}

Didée
28th December 2010, 14:25
MVTools is full of "why doesn't it find THIS?" surprises.

What caught my eye is the temporal=true parameter. With the interleave()-constructed source clip, temporal predictors are not valid: In worst case, the predictors are 100% in the wrong (i.e. opposite) direction!
Better use temporal=false in this case.

I fear that's not the only parameter you need to tweak (MVTools/MAnalyse has lots of them), but it's a necessary start.