Thread: rolling shutter
View Single Post
Old 18th April 2010, 04:51   #8  |  Link
um3k
Registered User
 
Join Date: May 2007
Posts: 220
It works pretty well, actually, except that it's a memory hog, somewhat unstable, extremely slow, etc. But it's a proof-of-concept, and gives acceptable results on small videos (and crashes on large ones). The good part is that it corrects all rolling shutter motion artifacts, both global and local, much like the Foundry plugin. Someone just needs to implement it as a subfunction of MVTools with optimizations, something which I am currently not capable of. Here is the latest version, though I have not messed with it in months:

Code:
#   RollAway filter by um3k/Justin Phillips
#   Reduces rolling shutter artifacts on video from CMOS-chipped camcorders/DSLRS
#   "Amount" is the same as that used for DeShaker. The formula can be found here:
#   http://www.guthspot.se/video/deshaker.htm#rolling shutter setting
#   "Segh" is the height of the segments the image is split into. It should be an even number, and a dividend of the clip height.
#   This script is compatible with SetMTMode.
#   Use SetMemoryMax in your script to increase speed. Set it to a fairly high number that is reasonable for you computer's capabilities.
#
#   Alpha 2

function RollAway_alpha2(clip c, float amount, int segh, bool "test", bool "flip", int "pel", int "blk", int "ovr", int "thSAD")
{
    Assert(c.height%segh == 0, "'segh' must be a dividend of clip height")
    ctime = amount/2.0
    segs = c.height/segh
    den = segs-1
    num = den
    test = Default(test, false)
    flip = Default(flip, false)
    pel = Default(pel, 1)
    blk = Default(blk, 16)
    ovr = Default(ovr, 12)
    thSAD = Default(thSAD, 100)
    super = c.MSuper(pel=pel)
    fv = MAnalyse(super, blksize=blk, isb = false, overlap=ovr)
    bv = MAnalyse(super, blksize=blk, isb = true, overlap=ovr)
    
    DeRoll(c, super, fv, bv, ctime, den, segh, t=test, flip=flip)
}

function DeRoll(clip c, clip super, clip fv, clip bv, float ctime, int den, int segh, int "segn", clip "stack", bool "t", bool "flip")
{
    stackh  = Defined(stack) ? stack.height
    \   :   0
    segn    = Defined(segn) ? segn+1
    \   :   0
    num     = abs(den-segn*2)
    fclp      = (flip==true) ? c.MFlow(super, bv, time=ctime*float(num)/float(den)).Crop(0, segn*segh, -0, segh).SelectEvery(1, -1)
    \   :   c.MFlow(super, fv, time=ctime*float(num)/float(den)).Crop(0, segn*segh, -0, segh).SelectEvery(1, 1)
    bclp     = (flip==true) ? c.MFlow(super, fv, time=ctime*float(num)/float(den)).Crop(0, segn*segh, -0, segh).SelectEvery(1, 1)
    \   :   c.MFlow(super, bv, time=ctime*float(num)/float(den)).Crop(0, segn*segh, -0, segh).SelectEvery(1, -1)
    nseg    = stackh > c.height/2 ? bclp
    \   :   fclp
    nseg = (t==true) ? nseg.Subtitle("num=" + String(num) + "  den=" + String(den) + "  segn=" + String(segn) + "  ctime=" + String(ctime*float(num)/float(den)))
    \   :   nseg
    stack   = Defined(stack) ? StackVertical(stack, nseg)
    \   :   nseg
    segn = segn    return stack.height == c.height ? stack
    \   :   DeRoll(c, super, fv, bv, ctime, den, segh, segn, stack, t, flip)
}
It basically motion compensates the frame numerous times, cuts up the frames, and recombines them into a new one. Needless to say, it is quite slow. Try it on a video downscaled to SD resolution, HD is practically guaranteed to crash.

I'd planned to put together a demo video, but, well, haven't.

Also, as a side note, it does not fully correct very fast motion, due to a limitation in MVTools. There's not really anything I can do about that.
um3k is offline   Reply With Quote