Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > VapourSynth

 
 
Thread Tools Search this Thread Display Modes
Prev Previous Post   Next Post Next
Old 29th May 2023, 11:12   #1  |  Link
Selur
Registered User
 
Selur's Avatar
 
Join Date: Oct 2001
Location: Germany
Posts: 7,150
Fill black frames with interpolations,...

Hi, I wrote two small functions:
  • ReplaceBlackFrames: replace a black frames with interpolations of the surrounding frames.
  • FillBlackFrames: replace a black frames with interpolations of the surrounding frames.
ReplaceBlackFrames works as expected.
Problem is FillBlackFrames, where I suspect that I messed up indices somewhere:
Code:
# replace the frames 'firstFrametoReplace' to 'firstGoodFrame-1' with interpolations between 'firstFrametoReplace - 1' and 'firstGoodFrame'
def fillMultipleWithSVP(clip, firstFrametoReplace=None, firstGoodFrame=None, gpu=False):
  clip1 = core.std.AssumeFPS(clip, fpsnum=1, fpsden=1)
  start = core.std.Trim(clip1, first=firstFrametoReplace-1, length=1) # last good frame before black frames
  end = core.std.Trim(clip1, first=firstGoodFrame, length=1) # first good frame after black frames
  startend = start + end
  if gpu:
    super  = core.svp1.Super(startend,"{gpu:1}")
  else:
    super  = core.svp1.Super(startend,"{gpu:0}")
  vectors= core.svp1.Analyse(super["clip"],super["data"],startend,"{}")

  # interpolate
  r = core.svp2.SmoothFps(startend,super["clip"],super["data"],vectors["clip"],vectors["data"],"{rate:{num:"+str(firstGoodFrame-firstFrametoReplace+1)+",den:1,abs:false}}")
  a = core.std.Trim(clip1, first=0, last=firstFrametoReplace-2) # last good frame before is part of r
  b = core.std.Trim(clip1, first=firstGoodFrame+1) # first good frame, ist part of r
  # join
  join = a + r + b
  if (join.num_frames != clip.num_frames): # did I messup with the join
    raise vs.Error(f"fillMultipleWithSVP: frame count issue join '{join.num_frames}' vs clip '{clip.num_frames}'")
  return core.std.AssumeFPS(join, src=clip)
  

# replace a black frames with interpolations of the surrounding frames.
# threshold average frame threshold
def FillBlackFrames(clip, thresh=0.1, debug=False):
    if not isinstance(clip, vs.VideoNode):
        raise ValueError('This is not a clip')
    
    def selectFunc(n, f):
        nonlocal clip
        firstGoodFrame = f.props['FirstGoodFrame']
        if n == 0:
          clip = core.std.SetFrameProp(clip, prop="FirstGoodFrame", intval=firstGoodFrame)
          return clip
        if firstGoodFrame >= n: # this frame, we already dealt with
            return clip

        if f.props['PlaneStatsAverage'] > thresh or n == 0:
            if debug:
                return core.text.Text(clip=clip, text="Org, avg: " + str(f.props['PlaneStatsAverage']), alignment=8)
            clip = core.std.SetFrameProp(clip, prop="FirstGoodFrame", intval=n)
            return clip
        firstFrametoReplace = n
        firstGoodFrame = n + 1
        for i in range(n, clip.num_frames-1):
            if clip.get_frame(i).props['PlaneStatsAverage'] <= thresh:
                continue
            firstGoodFrame = i
            break
        clip = core.std.SetFrameProp(clip, prop="FirstGoodFrame", intval=firstGoodFrame)
        replaced = fillMultipleWithSVP(clip, firstFrametoReplace, firstGoodFrame, gpu=True)
        if debug:
            return core.text.Text(clip=replaced, text="Replaced from " + str(firstFrametoReplace) + " to " + str(firstGoodFrame-1))
        return replaced
    clip = core.std.SetFrameProp(clip, prop="FirstGoodFrame", intval=0)
    clip = core.std.PlaneStats(clip)
    fixed = core.std.FrameEval(clip, selectFunc, prop_src=clip)
    return fixed

When I have a clip where:
Frame 19 is fine
Frame 20&21 are black
Frame 22 is fine
and I apply FillBlackFrames to it, both frame 20&21 get replaced, but frame 21 is the same as 22.

Does someone spot where I went wrong?
(Or is this caused by Vapoursynth not really supporting linear processing in script?)

Cu Selur

Latest version:on GitHub
__________________
Hybrid here in the forum, homepage

Last edited by Selur; 31st May 2023 at 18:59.
Selur is offline   Reply With Quote
 

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 17:58.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2023, vBulletin Solutions Inc.