View Single Post
Old 2nd January 2017, 20:08   #161  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Quote:
Would it be hard to modify the InPaintFunc script so it doesn't convert the whole frame to RGB?
I'll take a look, not promising anything.

Quote:
The weird green frames of which you speak.... are they something you've experienced in the output video? I've only ever seen them when using debug=true
It looks like I was wrong about DeblendLogo(), looks like weird green stuff is purely down to maybe filter ordering or something, I've added a couple of
bits to the script to set chroma=128 in a couple of mt_ calls, fixes the debug output and less worrying to look at. I might actually use this script now.
RM_logo.avs v0.6
Code:
# rm_logo() Version 0.6 -- 02.01.2016.
#  v0.6, fixed weird green frames in Debug=true mode, StainlessS.
#
# Script to help in the removal of channel logos or other distracting objects
#
# Required filters:
# AVSInpaint: Ver 2008-01-06
#             Discussion & Code : http://forum.doom9.org/showthread.php?t=133682
# ExInpaint:  Ver 0.1+
#             Code http://avisynth.org.ru/exinpaint/exinpaint.html
# mt_masktools: Ver 2.0.32+
#               Code http://manao4.free.fr/masktools-v2.0a32.zip
# removegrain: Ver 1.0 (8/2005)
#              Code  http://www.removegrain.de.tf
# fft3dfilter: Ver 2.1.1 or later
#              Code http://avisynth.org.ru/fft3dfilter/fft3dfilter.html
# ttempsmoothf Ver 0.9.4 or later
#              Code http://bengal.missouri.edu/~kes25c/
# medianblur Ver 0.8.4
#            Code http://www.avisynth.org/tsp/medianblur084.zip
#
function rm_logo( clip clp, string "logomask", string "loc",float "par", string "mode",int "percent",int "deblendfalloff",\
                  int "AlphaToRepair", float "RepairRadius", float "InpaintRadius", float "InpaintSharpness",\
                  float "InpaintPreBlur", float "InpaintPostBlur", string "cutsize", bool "lmask", int "pp", bool "debug", \
                  int "cutwidth", int "cutheight") {
    logomask         = default( logomask,           "" ) # file location of the logo, the must be masked in pure white
    loc              = default( loc,                "" ) # where is the logo, TR, TL, BR, BL for top right, top left, bottom right, bottom left
    cutsize          = default( cutsize,       "small" ) # how big a cut to make, small, medium, large
    cutwidth         = default( cutwidth,            0 ) # how wide a cut to make in pixels, -1 for full width of frame
    cutheight        = default( cutheight,           0 ) # how tall a cut to make in pixels, -1 for full height of frame
    par              = default( par,               1.0 ) # pixel aspect ratio
    mode             = default( mode,           "both" ) # deblend, inpaint or both
    percent          = default( percent,            25 ) # how much of the clip to analyse in creating color&alpha masks, more is better but slower
    deblendfalloff   = default( deblendfalloff,      5 ) # graidient fallout from logo mask
    AlphaToRepair    = default( AlphaToRepair,     130 ) # what is the luma value of the solid part of the logo
    RepairRadius     = default( RepairRadius,      1.0 ) # used to expand the mask for none alpha ie solid areas
    InpaintRadius    = default( InpaintRadius,     6.0 ) # radius around a damaged pixel from where values are taken when the pixel  is inpainted. Bigger values prevent
                                                         # inpainting in the wrong direction, but also create more blur
    InpaintSharpness = default( InpaintSharpness, 25.0 ) # Higher values can prevent blurring caused by high Radius values.
    InpaintPreBlur   = default( InpaintPreBlur,    1.5 ) # Standard deviation of the blur which is applied to the image before the structure tensor is computed. Higher values
                                                         # help connecting isophotes which have been cut by the inpainting region, but also increase CPU usage. PreBlur=0.0
                                                         # disables pre-blurring.
    InpaintPostBlur  = default( InpaintPostBlur,   5.0 ) # standard deviation of the blur which is applied to the structure tensors before they are used to determine the
                                                         # inpainting direction. Higher values help gather more directional information when there are only few valid pixels
                                                         # available, but increases CPU usage
    lmask            = default( lmask,            true ) # apply post process through a repair mask
    PP               = default( PP,                  1 ) # Post process function 0,1,2 to help reduce damage left behind by logo removal
    debug            = default( debug,           false ) # show mask to help in tunning the output

    # set up some values that we need to run
    clp_width   = width( clp )
    clp_height  = height( clp )
    RGB         = isRGB( clp )
    RGB32       = isRGB32( clp )
    RGB24       = isRGB24( clp )
    par         = ( par!= 1.0 ) ? float( clp_height ) / float( clp_width ) * par : 1.0
    percent     = ( percent < 0) ? 25 : (percent > 100) ? 100 : percent

    # Get the always fun input error checking done
    assert        ( logomask != "" , "You have to define a logomask")
    assert        ( loc      != "" , "You must provide a value for Loc UL,UR,LL,LR")
    assert        ( loc == "TR" || loc == "TL" || loc == "BR" || loc == "BL"  , "Loc must be one of TR, TL, BR, BL")
    assert        ( mode == "both" || mode == "inpaint" || mode == "deblend", "Specified mode doesn't exist.")

    # Get our crop locations based on the passed location
    loc         = UCase( loc )
    cutsize     = UCase( cutsize )
    multi       = ( cutsize == "SMALL" ) ? 2.25 : ( cutsize == "MEDIUM" ) ? 2.15 : 2
    chunk       = ( clp_height > 720 ) ? 2.9 : 3
    cutwidth    = ( cutwidth == 0 || cutwidth == -1 ) ? cutwidth : m4(cutwidth)
    cutheight   = ( cutheight == 0 || cutheight == -1 ) ? cutheight : m4(cutheight)

    a           = ( Rightstr( loc, 1 ) == "L" ) ? 0 : (cutwidth  == 0 ) ?  m4( (clp_width  / chunk )  * multi ) : (cutwidth  == -1 ) ? 0 :  (clp_width  - cutwidth)
    b           = ( Leftstr( loc, 1 )  == "T" ) ? 0 : (cutheight == 0 ) ?  m4( (clp_height / chunk )  * multi ) : (cutheight == -1 ) ? 0 :  (clp_height - cutheight)
    c           = ( Rightstr( loc, 1 ) == "R" ) ? 0 : (cutwidth  == 0)  ? -m4( (clp_width  / chunk )  * multi ) : (cutwidth  == -1 ) ? 0 : -(clp_width  - cutwidth)
    d           = ( Leftstr( loc, 1 )  == "B" ) ? 0 : (cutheight == 0 ) ? -m4( (clp_height / chunk )  * multi ) : (cutheight == -1 ) ? 0 : -(clp_height - cutheight)
    cropped     = clp.crop(a,b,c,d)

    # Anaylse the entire clip or a percentage for speed.
    snipSize    = round( framecount( cropped ) / (framecount( cropped ) * (percent / 100.0) ))
    analyse     = ( percent != 100 ) ? cropped.SelectRangeEvery( snipSize, 1 ) : cropped

    # Read in our logo mask, prepare it and crop out the corner of interest
    logo_mask   = imagesource(logomask,start=0,end=1)
    logo_mask   = logo_mask.crop(a,b,c,d)
    logo_mask   = logo_mask.ConvertToYV12(Matrix="PC.601")
    logo_mask   = logo_mask.DistanceFunction(255/deblendfalloff,PixelAspect=par).Greyscale

    # Clean the analyse clip to improve results
    analyse = (IsYV12(analyse)) ? analyse : analyse.ConvertToYV12
    analyse = analyse.TTempSmoothF(maxr=2,lthresh=256,cthresh=256,scthresh=255).converttoRGB24()
    input   = ( RGB24 == true ) ? cropped : cropped.converttoRGB24()

    # seperate out the directory and logo names so we can save a unique ebmp file
    sl           = logomask.revstr().findstr("\") - 1
    Assert((sl   >= 0),"specify a fully qualified directory and logomask name to use")
    logo_name    = (sl < 0  ) ? "" : rightstr(logomask,sl) # name and extension
    s2           = logo_name.findstr(".") - 1 # find the length of the extension
    logo_name    = leftstr(logo_name,s2) # just the name !
    Analyse_Name = logo_name + loc + string(percent) + "AnalyzeResult%06d.ebmp"

    # Time to run the analysis on the logo, we want the color map and alpha map out of the file.
    try {
      # Analyze is a bit slow so we only do it once and store the result in a file, check if it exists or if it has changed
      ImageSource(Analyse_Name,0,0)
      (Interleave( AssumeFPS(input.FrameRate), input.Trim(0,-2).AnalyzeLogo(logo_mask) ).FrameCount > 3) ? last : last
    }
    catch( dummy ) {
      # Nice catch, we are here since we need to perform our logo analysis as none already exists
      analyse.AnalyzeLogo(logo_mask)

      # The analysis is complete, save a frame (all frames are the same)
      Trim( 0, -1 )
      ImageWriter( logo_name + loc + string(percent) + "AnalyzeResult", 0, 1, "ebmp" )
    }

    # The color map is the top half of the Analyze result, The alpha channel is in the bottom half
    AssumeFPS(analyse.FrameRate)
    LogoColor = Crop(0,0,0,last.Height/2)
    LogoAlpha = Crop(0,last.Height/2,0,0).ConvertToYV12(Matrix="PC.601")

    # Create a Deblend mask, this is a mask that falls off the marked logo area, we use this to blend the delogoed area back into the clip
    DeblendMask = logo_mask.DistanceFunction( 255.0 / DeblendFalloff, PixelAspect=par )

    # Create a repair mask for pixels that cannot be deblended
    LogoAlpha.Invert.mt_lut(expr="x " + " " + string(alphatorepair) + " " + "< 255 0 ?").mt_expand.mt_inflate(chroma="-128") # ssS, added (chroma="-128")
    RepairMask = ( RepairRadius > 0.1 ) ? DistanceFunction( 84.0 / RepairRadius, PixelAspect=par ) : last

    # InpaintLogo and DeblendLogo based on user preferance
    deblend    = ( mode == "both" ) ? input.DeblendLogo(LogoColor,LogoAlpha) \
               : ( mode == "deblend" ) ? input.DeblendLogo(logoColor,logoAlpha) : input

    repaired   = ( mode == "both" ) ? deblend.InpaintLogo(RepairMask, Radius=InpaintRadius, Sharpness=InpaintSharpness, \
                                      PreBlur=InpaintPreBlur, PostBlur=InpaintPostBlur, PixelAspect=par) \
               : ( mode == "inpaint" ) ? deblend.InpaintLogo(RepairMask,Radius=InpaintRadius, Sharpness=InpaintSharpness, PreBlur=InpaintPreBlur,\
                                         PostBlur=InpaintPostBlur, PixelAspect=par) : deblend

    #repaired = ExInpaint (repaired.converttorgb32, repairmask.converttorgb32, color=$ffffff,xsize=5, ysize=3, radius=36)

    output = Layer(input.ConvertToRGB32, repaired.ConvertToRGB32.Mask(DeblendMask.ConvertToRGB32(Matrix="PC.601")))
    output = output.converttoyv12

    # post processing of the results if requested
    postmask = LogoAlpha.Invert.mt_lut(expr="x " + " " + string(alphatorepair) + " " + "< 255 0 ?").mt_expand.mt_inflate(chroma="-128") # ssS, added (chroma="-128")
    postmask = postmask.DistanceFunction( 64.0 / RepairRadius, PixelAspect=par )

    #postmask = (pp > 0 && lmask) ? repairmask.DistanceFunction( 512.0 / DeblendFalloff, PixelAspect=par ) : blankclip(output,color=$000000)
    post = ( PP == 1 ) ? output.minblur(1,uv=3).medianblur(3,0,0).removegrain(11)  \
         : ( pp == 2 ) ? output.fft3dfilter(sigma=16,sigma2=12,sigma3=8,sigma4=4,bt=3,bw=16,bh=16,ow=8,oh=8,plane=4) \
         : ( pp == 3 ) ? output.mt_convolution("1 8 28 56 76 56 28 8 1","1 8 28 56 76 56 28 8 1",y=3,v=2,u=2) \
         : output
    output = ( pp > 0 ) ? mt_merge(output,post,postmask) : output

    aa = debug ? stackhorizontal(logo_mask.ConvertToYV12.subtitle("logo mask"),logocolor.ConvertToYV12.subtitle("Logo Color"),logoalpha.ConvertToYV12.subtitle("Logo Alpha")) : nop
    bb = debug ? stackhorizontal(deblendmask.ConvertToYV12.subtitle("Deblend Mask"),repairmask.ConvertToYV12.subtitle("Repair Mask"),postmask.ConvertToYV12.subtitle("Post Mask")) : nop
    cc = debug ? stackhorizontal(cropped.ConvertToYV12.subtitle("Original"),repaired.ConvertToYV12.subtitle("Repaired"),output.ConvertToYV12.subtitle("Post")) : nop

    # Almost done, lets blend in our repair
    output = (RGB == true) ? (RGB24 == true) ? output : output.converttoRGB32() : output.converttoYV12()
    final   = clp.overlay(output,a, b)

    RETURN debug ? stackvertical(aa,bb,cc) : final
}

FUNCTION MinBlur(clip input, int r, int "uv") {
    # Nifty Gauss/Median combination
    # Taken from MCBob.avs:
    uv   = default(uv,3)

    # process chroma if uv==3, otherwise just luma
    uv2  = (uv==2) ? 1  : uv
    rg4  = (uv==3) ? 4  : -1
    rg11 = (uv==3) ? 11 : -1
    rg20 = (uv==3) ? 20 : -1
    medf = (uv==3) ? 1  : -200

    # make our blur clips, r controls amount
    RG11D = (r==1) ? mt_makediff(input,input.removegrain(11, rg11),U=uv2,V=uv2)
    \    : (r==2) ? mt_makediff(input,input.removegrain(11,rg11).removegrain(20,rg20),U=uv2,V=uv2)
    \    :          mt_makediff(input,input.removegrain(11,rg11).removegrain(20,rg20).removegrain(20,rg20),U=uv2,V=uv2)
    RG4D  = (r==1) ? mt_makediff(input,input.removegrain(4,rg4),U=uv2,V=uv2)
    \    : (r==2) ? mt_makediff(input,input.medianblur(2,2*medf,2*medf),U=uv2,V=uv2)
    \    :          mt_makediff(input,input.medianblur(3,3*medf,3*medf),U=uv2,V=uv2)
    DD    = mt_lutxy(RG11D,RG4D,"x 128 - y 128 - * 0 < 128 x 128 - abs y 128 - abs < x y ? ?",U=uv2,V=uv2)
    RETURN (input.mt_makediff(DD,U=uv,V=uv))
}

FUNCTION m4(float x) {RETURN( x<16?16:int(round(x/4.0)*4)) }
2 Mods Marked in Blue.

EDIT: If you spot any more green frames in Debug, shout out and give args and I'll take another look, there are other calls to MT_
that do not have chroma setting set.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 2nd January 2017 at 20:14.
StainlessS is offline   Reply With Quote