Thread: rolling shutter
View Single Post
Old 20th June 2010, 12:16   #15  |  Link
cretindesalpes
͡҉҉ ̵̡̢̛̗̘̙̜̝̞̟̠͇̊̋̌̍̎̏̿̿
 
cretindesalpes's Avatar
 
Join Date: Feb 2009
Location: No support in PM
Posts: 712
I tried to improve the speed and memory usage of the script. I ended up modifying the MVTools2 to let MFlow() accept the motion compensation time parameter as a clip, the time being defined for each pixel instead of a single scalar for the whole clip.

The visual quality hasn't changed but it resulted in a x10 speed up improvement over the original script (tested on terka's example camileo3.mp4 with segh=4 and pel=4). And now that the memory usage has become fair, it is possible to SetMTMode() it on HD material, giving an impressive x40 speed boost on a quad core CPU!

I also tried the same thing on MFlowInter() but the results were disappointing. It generates much more artifacts than a simple MFlow(). However I kept it in the script so you can try to play with it and find better parameters.

You can find the modified MVTools2 in this package. And the updated script below:

Code:
#   RollAway filter by um3k/Justin Phillips/Firesledge
#   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
#   This script is compatible with SetMTMode.
#
#   Alpha 2 mod
function RollAway_alpha2mod (clip c, float amount, bool "flip", int "pel", int "blk", int "ovr", bool "inter")
{
    #
    # Just syntactic housekeeping:  Define default values and set up some paramters.
    #
    flip  = Default(flip,  false)
    inter = Default(inter, false)
    pel   = Default(pel,       1)
    blk   = Default(blk,      16)
    ovr   = Default(ovr,      12)

    #
    # We'll split the picture at a height multiple of 4, and this split
    # line is used as the reference time (no motion interpolation here).
    # Therefore we need that the time function equals 0 at this line :
    # t = amount * abs (ofs - y), with ofs close to 0.5 and y in
    # the range 0 to 1.
    # MFlowInter() timeclip formula is a bit different.
    #
    w = c.Width ()
    h = c.Height ()
    sy = 4 * Round (h / 8)	# Split line
    ofs = Float (sy) / Float (h)

    OFS = String (ofs)
    AMT = String (amount)
    expr_norm  = OFS + " y - abs " + AMT + " * 2.56 *"
    expr_inter = OFS + " y - " + AMT + " * 2.56 * y " + OFS + " >= 256 0 ? +"
    expr = (inter) ? expr_inter : expr_norm

    #
    # Just uses MVTools - See http://avisynth.org.ru/mvtools/mvtools2.html
    # MSuper heirarchically decomposes the clip, while MAnalyse prepares
    # the motion vectors.
    #
    super = c.MSuper(pel=pel)
    fv = MAnalyse(super, blksize=blk, overlap=ovr, truemotion=true, searchparam=8, isb = false)
    bv = MAnalyse(super, blksize=blk, overlap=ovr, truemotion=true, searchparam=8, isb = true )

    #
    # "flip" allows you to switch the forward and backward clips - I can't
    # figure out why exactly.  I think that it's for field parity for
    # interlaced videos.
    #
    timeclip = c.mt_lutspa (relative=true, expr=expr, y=3, u=3, v=3)
    fclp =
\     (inter) ? c.MFlowInter (super, bv, fv, tclip=timeclip)
\   : (flip ) ? c.MFlow(super, bv, tclip=timeclip).SelectEvery(1, -1)
\   :           c.MFlow(super, fv, tclip=timeclip).SelectEvery(1,  1)
    bclp =
\     (inter) ? fclp.SelectEvery(1, -1)
\   : (flip ) ? c.MFlow(super, fv, tclip=timeclip).SelectEvery(1,  1)
\   :           c.MFlow(super, bv, tclip=timeclip).SelectEvery(1, -1)

    #
    # Figure out which segment of the stack we're at (past halfway?), and
    # whether we should be using a segment forward-interpolated from the last
    # frame, or back-interpolated from the next frame.
    #
    top = fclp.Crop (0, 0, w, sy)
    bot = bclp.Crop (0, sy, w, h - sy)
    stack = StackVertical (top, bot)

    return (stack)
}

Last edited by cretindesalpes; 20th June 2010 at 12:22. Reason: Typo
cretindesalpes is offline   Reply With Quote