View Single Post
Old 29th August 2014, 20:11   #2  |  Link
raffriff42
Retried Guesser
 
raffriff42's Avatar
 
Join Date: Jun 2012
Posts: 1,373
I hate that "twinkling/shimmering" effect as well. Your solution is very good, considering how hard the problem is (whether at real time or not), but I have a few thoughts:

* adding the results of mt_motion from the 2 previous frames seems to help catch more of the movement. Note the functions calls I used to do this were only used because I had these functions on hand; there are certainly other (better) ways to do the same thing.

* for temporal smoothing, take a look at FFT3DFilter in place of MCompensate. It may be only a personal preference (ie, which artifacts are more annoying for you), but I think FFT3DFilter looks a little better. Not sure how speed might be affected on your system. Again, I used a function I had worked up previously.

Code:
# mt_masktools-26.dll
# nnedi3.dll
# fft3dfilter211\FFT3DFilter.dll

AviSource("D:\VideoProjects\raw\mgs3motion uty7.avi")
ConvertToYV12(matrix="Rec709", chromaresample="spline16")
out_wid=1870
out_hgt=1050

#-Settings-------------------
## Spatial anti-aliasing, runs on GPU. 
## 2x for resolutions around 1280x720, 4x for larger screens if you have spare power.
FSAA=2 
## Temporal anti-aliasing, runs on CPU. 
## Reduces flickering in motion, possible values 2 or 3. 0 disables it.
TXAA=2
## HDR dynamic contrast. Increases visibility in overly bright or dark areas. 
## Values list: 0, 0.25, 0.5, 0.75, 1(>0.5 is not recommended).
HDR=0 /* not tested */
#/Settings------------------

Last = (HDR<=0) ? Last
\ : raveragew(Last, 1-HDR, ColorYUV(autogain=true ), HDR, mode=4, u=3, v=3, lsb_out=true)
\     .ditherpost()

uv = BicubicResize(out_wid, out_hgt)

#super = MSuper(pel=2, chroma=false) 
#backward_vectors = MAnalyse(super, blksize=8, 
#\                       overlap=2, search=4, 
#\                       truemotion=true,  chroma=false, temporal=true, 
#\                       badsad=1000, isb=true) 
#forward_vectors  = MAnalyse(super, blksize=16, blksizev=8, 
#\                       overlap=0, overlapv=2, search=4, 
#\                       truemotion=false, chroma=false, temporal=true, 
#\                       badsad=1000, isb=false) 
#backward_compensation = MCompensate(super, backward_vectors, thSCD1=600)
#forward_compensation  = MCompensate(super, forward_vectors,  thSCD1=400)  
#AA = (TXAA==3)
#\      ? Merge(Merge(forward_compensation, backward_compensation).Sharpen(0.2), 0.67)
#\      : Merge(backward_compensation) 

AA = AAff3d_10(temporal_size=4, sigma=6.0, sharpen=0.0) /* FFT3DFilter? */

me = mt_edge(mode="laplace", thy1=0, thy2=10, u=1, v=1).mt_inflate

mm = mt_motion(thy1=0, thy2=15, tht=100, u=1, v=1).mt_expand.mt_inflate
mm  = mm.UUDelayBlend(1, 1.0, "lighten").UUDelayBlend(2, 1.0, "lighten") /* multiple mt_motion? */

m  = mt_logic(me, mm, mode="min", u=1, v=1).mt_expand(mode="both").Blur(0.5)  

Last = (TXAA<=0) ? Last
\    : mt_merge(AA, m, u=1, v=1)
 
nnedi3x_rpow2(rfactor=FSAA,  u=false, v=false, nns=2)

Spline16Resize(out_wid, out_hgt) /* less ringy; a little faster? */

MergeChroma(uv)

Sharpen(Min(0.33*FSAA, 1.0)).Blur(0.1)

return Last 

#######################################
### FFT 3D antialising: decreases certain aliasing artifacts, 
##  such as moire and shimmer; spatial & temporal smoothing. 
##
## @ temporal_size: default 5; try 1-4 for faster processing 
##            0 - all previous frames (switch Kalman filter mode);
##            1 - only current frame (spatial 2D Wiener filter);
##            2 - previous and current frame (3D Wiener filter);
##            3 - previous, current and next frame (3D Wiener filter)
##          * 4 - two previous, current and next frame (3D Wiener filter)
##          * 5 - two previous, current and two next frames (3D Wiener filter)
##           -1 - sharpen only (2D);
##
## @ sigma - given noise value (float>0, default=12)
##           1.5 = subliminal
##           2.2 = slightly soft
##           3.0 = soft
##           5.0 = softer
##           (default 12 = very strong)
##
## @ sharpen - sharpening strength; good values about 0.3 to 1.0; 
##            negative values results in reverse effect.
##            (default=0.5 - slight sharpening)
##
## suggested settings: 
##   AAff3d_10()       ##  strong
##   AAff3d_10(4, 10)  ##  less strong
##   AAff3d_10(4, 2.2) ## slightly soft
##
function AAff3d_10(clip C, int "temporal_size", float "sigma", float "sharpen")
{
    Assert(C.IsYV12 || C.IsYUY2, 
    \     "AAff3d_10: invalid source format")
    sigma   = Float(Default(sigma, 12))
    sigma4  = sigma+20 ## given noise value at lowest frequencies
    
    sharpen = Float(Default(sharpen, 0.5))
    
    temporal_size = Default(temporal_size, 5)
    Assert((-2<temporal_size && 6>temporal_size),
    \     "AAff3d_10: invalid temporal_size argument")

    ## bw, bh - block width, height
    blksiz = 24
    ## ow, oh - overlap width, height
    ovrlap =  8 ## blksiz / 3

    C ## Last=C
    FFT3DFilter(sigma=sigma, sigma4=sigma4, bw=blksiz, bh=blksiz, 
    \           bt=temporal_size, ow=ovrlap, oh=ovrlap, sharpen=sharpen, 
    \           ncpu=2)
}

#######################################
### delay blend
#
#@param frames  - amount of delay (1 to 3 frames)
#@param opacity - amount of delayed video (from 0.0 to 1.0; default=0.5)
#@param mode    - Overlay mode (default "blend")
#
function UUDelayBlend(clip C, int "frames", float "opacity", string "mode")
{
    frames  =       Min(Max(1, Default(frames,  1  )), 3) 
    opacity = Float(Min(Max(0, Default(opacity, 0.5)), 1))
    mode    =                  Default(mode,    "blend")

    return Overlay(C, C.UUSlip(-frames), opacity=opacity, mode=mode)
}

#######################################
### "slip" a clip in time.
##
## @ C - clip to be advanced or delayed 
## @ offset - if positive, clip is advanced;
##            if negative, clip is delayed
## @ P - clip to be used for padding (default = BlankClip) 
##
function UUSlip(clip C, int offset, clip "P")
{
    lenTrim = (offset > 0) ? offset : 0
    lenPad  = (offset < 0) ? -offset : 0

    P = IsClip(P) ? P : BlankClip(C)

    C = (lenPad==0) ? C 
    \ : P.Trim(0, -lenPad) + C

    C = (lenTrim==0) ? C 
    \ : C.Trim(lenTrim, 0) + P.Trim(P.Framecount-lenTrim, -lenTrim) 

    return C
}

__END__

Last edited by raffriff42; 29th August 2014 at 20:19.
raffriff42 is offline   Reply With Quote