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
Register FAQ Today's Posts Search

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,169
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,169
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,169
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: 149
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,659
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, its own forum
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,659
https://forum.doom9.org/showthread.php?t=182961 maybe ?
__________________
Hybrid here in the forum, homepage, its own forum
Selur is offline   Reply With Quote
Old 19th October 2023, 15:41   #13  |  Link
kedautinh12
Registered User
 
Join Date: Jan 2018
Posts: 2,169
Did you try with IT, Ceppo??
https://github.com/Asd-g/AviSynthPlu...ent-1771105416
kedautinh12 is offline   Reply With Quote
Old 2nd February 2024, 16:47   #14  |  Link
kedautinh12
Registered User
 
Join Date: Jan 2018
Posts: 2,169
Asd-g ask you license to update Ctools, Ceppo
https://github.com/Asd-g/AviSynthPlu...ent-1923731799
kedautinh12 is offline   Reply With Quote
Old 3rd February 2024, 13:30   #15  |  Link
takla
Registered User
 
Join Date: May 2018
Posts: 215
Quote:
Originally Posted by Ceppo View Post
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
""")
Much better then:
Code:
-vf "dejudder, fps=30000/1001, fieldmatch=mode=pcn_ub:combmatch=full, yadif=deint=interlaced, decimate"
Thanks!

Last edited by takla; 20th February 2024 at 22:36.
takla is offline   Reply With Quote
Old 14th February 2024, 13:13   #16  |  Link
takla
Registered User
 
Join Date: May 2018
Posts: 215
Any way to deinterlace unmatchable fields with this?
takla is offline   Reply With Quote
Reply


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 04:31.


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