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 > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 2nd October 2023, 23:56   #1  |  Link
Ceppo
Registered User
 
Join Date: Feb 2016
Location: Nonsense land
Posts: 339
Very Effective Field Matching script

Sorry, I disappeared, but soon I will again. However, today I was playing with avisynth and I found a nice way to make field matching thanks to the VMAF2 plugin. Basically you make a c/n/p match clips, then you deinterlace them with a simple vertical blur, then you make a comparison using the PSNR metric. The highest wins, of course. Works in 99.9% of the cases on my source. I don't have time to make a plugin so, if someone likes it, please do.

Code:
mpeg2Source("VTS_01_1.d2v")
global c = last
global n = DoubleWeave(c).SelectOdd()
global p = DoubleWeave(c).SelectOdd().DuplicateFrame(0)
global c = VMAF2(c,Blur(c,0,1),feature = 0)
global n = VMAF2(n,Blur(n,0,1),feature = 0)
global p = VMAF2(p,Blur(p,0,1),feature = 0)
c
ScriptClip("""
propGetFloat(n,"psnr_y") > propGetFloat(c,"psnr_y")  ? n : \
propGetFloat(p,"psnr_y") > propGetFloat(c,"psnr_y")  ? p : c
""")
The PSNR metric can be also used to detect duplicates to do decimation, since duplicate have a very high PSNR score.
Ceppo is offline   Reply With Quote
Old 3rd October 2023, 02:23   #2  |  Link
kedautinh12
Registered User
 
Join Date: Jan 2018
Posts: 2,035
any chance in this situation for the first part??
https://forum.doom9.org/showthread.p...02#post1992102

Last edited by kedautinh12; 3rd October 2023 at 08:05.
kedautinh12 is offline   Reply With Quote
Old 3rd October 2023, 07:07   #3  |  Link
Ceppo
Registered User
 
Join Date: Feb 2016
Location: Nonsense land
Posts: 339
Not sure what you mean.
Ceppo is offline   Reply With Quote
Old 3rd October 2023, 08:05   #4  |  Link
kedautinh12
Registered User
 
Join Date: Jan 2018
Posts: 2,035
Quote:
Originally Posted by Ceppo View Post
Not sure what you mean.
Sr for my bad English, edited
kedautinh12 is offline   Reply With Quote
Old 3rd October 2023, 13:26   #5  |  Link
Ceppo
Registered User
 
Join Date: Feb 2016
Location: Nonsense land
Posts: 339
I have no idea.

BTW, never used vapoursynth but I did a version for it too.
Code:
import vapoursynth as vs
core = vs.core

c = core.d2v.Source("VTS_01_1.d2v")
n = core.std.SeparateFields(c)
n = core.std.DoubleWeave(n)
n = core.std.SelectEvery(n,2,1)
p = core.std.DuplicateFrames(n,0)

c = core.vmaf.Metric(c,core.std.BoxBlur(c,hradius=0),0)
n = core.vmaf.Metric(n,core.std.BoxBlur(n,hradius=0),0)
p = core.vmaf.Metric(p,core.std.BoxBlur(p,hradius=0),0)

def SelectFrame(n, f):
   A = f[0].props["psnr_y"]
   B = f[1].props["psnr_y"]
   C = f[2].props["psnr_y"]
   if B > A:
       return f[1]
   elif C > A:
       return f[2]
   else:
       return f[0]

core.std.ModifyFrame(clip=c,clips=[c, n, p],selector=SelectFrame).set_output()
Ceppo is offline   Reply With Quote
Old 3rd October 2023, 13:46   #6  |  Link
kedautinh12
Registered User
 
Join Date: Jan 2018
Posts: 2,035
Selur will happy for it
kedautinh12 is offline   Reply With Quote
Old 3rd October 2023, 16:19   #7  |  Link
Ceppo
Registered User
 
Join Date: Feb 2016
Location: Nonsense land
Posts: 339
With vinverse we are at the 100% of correct match on my source.
Code:
mpeg2Source("VTS_01_1.d2v")
global c = last
global n = DoubleWeave(c).SelectOdd()
global p = DoubleWeave(c).SelectOdd().DuplicateFrame(0)
global c = VMAF2(c,vinverse(c),feature = 0)
global n = VMAF2(n,vinverse(n),feature = 0)
global p = VMAF2(p,vinverse(p),feature = 0)
c
ScriptClip("""
propGetFloat(n,"psnr_y") > propGetFloat(c,"psnr_y")  ? n : \
propGetFloat(p,"psnr_y") > propGetFloat(c,"psnr_y")  ? p : c
""")
Ceppo is offline   Reply With Quote
Old 3rd October 2023, 20:45   #8  |  Link
SaurusX
Registered User
 
Join Date: Feb 2017
Posts: 124
Very interesting. I've got just the project to test this on.
SaurusX is offline   Reply With Quote
Old 3rd October 2023, 22:07   #9  |  Link
Ceppo
Registered User
 
Join Date: Feb 2016
Location: Nonsense land
Posts: 339
This should be more precise.

Code:
global c = last
global n = DoubleWeave(c).SelectOdd()
global p = DoubleWeave(c).SelectOdd().DuplicateFrame(0)
global c = VMAF2(c,vinverse(c),feature = 0)
global n = VMAF2(n,vinverse(n),feature = 0)
global p = VMAF2(p,vinverse(p),feature = 0)
c
ScriptClip("""
n_metric = propGetFloat(n,"psnr_y") + propGetFloat(n,"psnr_cb") + propGetFloat(n,"psnr_cr")
c_metric = propGetFloat(c,"psnr_y") + propGetFloat(c,"psnr_cb") + propGetFloat(c,"psnr_cr")
p_metric = propGetFloat(p,"psnr_y") + propGetFloat(p,"psnr_cb") + propGetFloat(p,"psnr_cr")
n_metric > c_metric && n_metric > p_metric ? n : \
p_metric > c_metric && p_metric > n_metric ? p : c
""")
Ceppo is offline   Reply With Quote
Old 15th October 2023, 10:39   #10  |  Link
Selur
Registered User
 
Selur's Avatar
 
Join Date: Oct 2001
Location: Germany
Posts: 7,151
Can't get the Vapoursynth version working.
I used the code from post #5, packed it into a function and adjusted SelectFrame, where:
Code:
  if B > A:
       return f[1]
   elif C > A:
       return f[2]
   else:
       return f[0]
to:
Code:
     if B > A:
       if B > C:
         return f[1]
       return f[2]
     elif C > A:
         return f[2]
     else:
         return f[0]
I ended up with:
Code:
# FieldMatching from https://forum.doom9.org/showthread.php?t=185104 by Ceppo
# requires: 
#   havsfunc https://github.com/Selur/VapoursynthScriptsInHybrid/blob/master/havsfunc.py when Vinverse is enabled (!not working atm!)
#   VMAF: https://github.com/HomeOfVapourSynthEvolution/VapourSynth-VMAF
def cFieldMatch(clip: vs.VideoNode, chroma: bool=False, vinverse: bool=False):
  # prepare
  n = clip
  n = core.std.SeparateFields(clip=n) # separate frames
  n = core.std.DoubleWeave(clip=n) # double weave
  n = core.std.SelectEvery(clip=n, cycle=2, offsets=1) # select odd
  p = core.std.DuplicateFrames(clip=n, frames=[0]) # duplicate first frame

  # calculate PSNR 
  if vinverse: 
    import havsfunc
    c = core.vmaf.Metric(reference=clip, distorted=havsfunc.Vinverse(clip), feature=[0])
    n = core.vmaf.Metric(reference=n,    distorted=havsfunc.Vinverse(n),    feature=[0])
    p = core.vmaf.Metric(reference=p,    distorted=havsfunc.Vinverse(c),    feature=[0])
  else:
    c = core.vmaf.Metric(reference=clip, distorted=core.std.BoxBlur(clip,hradius=0), feature=[0])
    n = core.vmaf.Metric(reference=n,    distorted=core.std.BoxBlur(n,hradius=0),    feature=[0])
    p = core.vmaf.Metric(reference=p,    distorted=core.std.BoxBlur(p,hradius=0),    feature=[0])
  
  def SelectFrameChroma(n, f):
     A = f[0].props["psnr_y"] + f[0].props["psnr_cb"] + f[0].props["psnr_cr"] # c
     B = f[1].props["psnr_y"] + f[1].props["psnr_cb"] + f[1].props["psnr_cr"] # n
     C = f[2].props["psnr_y"] + f[2].props["psnr_cb"] + f[2].props["psnr_cr"] # p
     # return max
     if B > A:
       if B > C:
         return f[1]
       return f[2]
     elif C > A:
         return f[2]
     else:
         return f[0]
  def SelectFrame(n, f):
     A = f[0].props["psnr_y"] # c
     B = f[1].props["psnr_y"] # n
     C = f[2].props["psnr_y"] # p
     # return max
     if B > A:
       if B > C:
         return f[1]
       return f[2]
     elif C > A:
         return f[2]
     else:
         return f[0]
  # select
  if chroma:
    return core.std.ModifyFrame(clip=c, clips=[c, n, p], selector=SelectFrameChroma)
  return core.std.ModifyFrame(clip=c, clips=[c, n, p], selector=SelectFrame)
The problem is: It does not work. At least here, it does not field match at all.

Does anyone have an idea why it does not work?

Cu Selur
__________________
Hybrid here in the forum, homepage
Selur is offline   Reply With Quote
Old 16th October 2023, 19:01   #11  |  Link
Ceppo
Registered User
 
Join Date: Feb 2016
Location: Nonsense land
Posts: 339
Let me change the problem. Is there a tutorial/sample for making vapoursynth plugins?
Ceppo is offline   Reply With Quote
Old 17th October 2023, 18:13   #12  |  Link
Selur
Registered User
 
Selur's Avatar
 
Join Date: Oct 2001
Location: Germany
Posts: 7,151
https://forum.doom9.org/showthread.php?t=182961 maybe ?
__________________
Hybrid here in the forum, homepage
Selur is offline   Reply With Quote
Old 19th October 2023, 15:41   #13  |  Link
kedautinh12
Registered User
 
Join Date: Jan 2018
Posts: 2,035
Did you try with IT, Ceppo??
https://github.com/Asd-g/AviSynthPlu...ent-1771105416
kedautinh12 is offline   Reply With Quote
Reply

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 03:38.


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