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 20th December 2005, 15:36   #1  |  Link
actionman133
Movie buff & shine
 
Join Date: Jan 2004
Location: Logan, the only hole above ground.
Posts: 257
A new attempt at good deblending

Hi,

Of course no one would remember that a long time ago, I attempted to create a deblend function for correcting films that underwent telecine and then had the fields blurred together.

I wasn't very successful then, but just tonight I'm trying a slightly different approach but I am stuck on how to use FrameEvaluate... the help guide might as well be inverted chinese algebra, because it makes me go crosseyed (rest of the guide is good, though).

Here is the test script to set up the detection process.

Code:
Function DeBlend (clip Last) {

a = Subtract (Last, Trim (1, 0).Levels (0, 1, 255, 128, 255, False)).Levels (0, 1, 127, 0, 255, False).Trim (1, 0)
b = Subtract (Levels (0, 1, 255, 0, 127, False), Trim (1, 0)).Levels (0, 1, 127, 255, 0, False).DuplicateFrame (0)

StackVertical (Last, a, b)

}
The result of this test is the original clip displayed on top, with two deblended frames beneath them. Those two deblended frames should be identical when the first blended frame in the pattern appears in the original clip.

That's worked fine for me so far. Where FrameEvaluate () comes in and messes me up is how to have the function work out whether to deblend or not. Here is the script I more or less came up with (I know the syntax is WAAAY out)...

Code:
Function DeBlend (clip Last) {

# Perform Deblends for the comparison test
a = Subtract (Last, Trim (1, 0).Levels (0, 1, 255, 128, 255, False)).Levels (0, 1, 127, 0, 255, False).Trim (1, 0)
b = Subtract (Levels (0, 1, 255, 0, 127, False), Trim (1, 0)).Levels (0, 1, 127, 255, 0, False).DuplicateFrame (0)

# Get difference between two tests
Global Test = Subtract (a, b)

# Get difference for each pair of frames in a 5 frame set
ab = FrameEvaluate ("YPlaneMinMaxDifference (Test.SelectEvery (5, 0))")
bc = FrameEvaluate ("YPlaneMinMaxDifference (Test.SelectEvery (5, 1))")
cd = FrameEvaluate ("YPlaneMinMaxDifference (Test.SelectEvery (5, 2))")
de = FrameEvaluate ("YPlaneMinMaxDifference (Test.SelectEvery (5, 3))")
ea = FrameEvaluate ("YPlaneMinMaxDifference (Test.SelectEvery (5, 4))")

# Find the frame which had the lowest difference in the two tests
Dupe = (ab > bc) ? "bc" : "ab"
Dupe = (Eval (Dupe) > cd) ? "cd" : Dupe
Dupe = (Eval (Dupe) > de) ? "de" : Dupe
Dupe = (Eval (Dupe) > ea) ? "ea" : Dupe

# Use SelectEvery to delete Dupe... not yet implemented

}
The FrameEvaluate () section is supposed to calculate the difference between the two deblend tests (a & b). The Dupe variable tests to find out which of these frames produced the smallest difference in those tests. The SelectEvery () piece will then remove the blended frames and replace them with a single deblended frame.

Now, for those who made it this far.... ... how do I properly implement FrameEvaluate () to retrieve the comparitive differences between a and b?

Thanks.
__________________
I'm a boxer who can Bob () & Weave (). I like to Overlay () punches and Blur () his vision to ShowFiveVersions (). My KO punch will always Pulldown ().TimeStretch () and all he will hear is Tone ().
actionman133 is offline   Reply With Quote
Old 20th December 2005, 16:10   #2  |  Link
Didée
Registered User
 
Join Date: Apr 2002
Location: Germany
Posts: 5,389
Without checking anything, just putting the "conditionalities" in order: (hopefully)

Code:
Function DeBlend (clip clp) {

global ab = 0.0
global bc = 0.0
global cd = 0.0
global de = 0.0
global ea = 0.0

# Perform Deblends for the comparison test
a = Subtract (clp, clp.Trim (1, 0).Levels (0, 1, 255, 128, 255, False)).Levels (0, 1, 127, 0, 255, False).Trim (1, 0)
b = Subtract (clp.Levels (0, 1, 255, 0, 127, False), clp.Trim (1, 0)).Levels (0, 1, 127, 255, 0, False).DuplicateFrame (0)

# Get difference between two tests
Global Test = Subtract (a, b)

# Get difference for each pair of frames in a 5 frame set
FrameEvaluate(clp, "global ab = YPlaneMinMaxDifference (Test.SelectEvery (5, 0))")
FrameEvaluate(clp, "global bc = YPlaneMinMaxDifference (Test.SelectEvery (5, 1))")
FrameEvaluate(clp, "global cd = YPlaneMinMaxDifference (Test.SelectEvery (5, 2))")
FrameEvaluate(clp, "global de = YPlaneMinMaxDifference (Test.SelectEvery (5, 3))")
FrameEvaluate(clp, "global ea = YPlaneMinMaxDifference (Test.SelectEvery (5, 4))")

# Find the frame which had the lowest difference in the two tests
Dupe = (ab > bc) ? "bc" : "ab"
Dupe = (Eval (Dupe) > cd) ? "cd" : Dupe
Dupe = (Eval (Dupe) > de) ? "de" : Dupe
Dupe = (Eval (Dupe) > ea) ? "ea" : Dupe

# Use SelectEvery to delete Dupe... not yet implemented

}
edit: FrameEvaluate needs a clip argument, too ...

Notes:

- PLEASE don't you use "Last" as name for a variable or function argument.
- you still need to do something with "Dupe"
- except for rare cases, you won't have much fun with a SelectEvery-decimation ...
__________________
- We´re at the beginning of the end of mankind´s childhood -

My little flickr gallery. (Yes indeed, I do have hobbies other than digital video!)

Last edited by Didée; 20th December 2005 at 16:29.
Didée is offline   Reply With Quote
Old 20th December 2005, 16:30   #3  |  Link
actionman133
Movie buff & shine
 
Join Date: Jan 2004
Location: Logan, the only hole above ground.
Posts: 257
Thanks, the script is running now, except it's not working properly. The Framevaluate seems to not work as all the values are returned as 0.000000.

It's as if it's reading the original global declarations, and ignoring FrameEvaluate completely...

Any ideas?

EDIT: Just read your notes at the bottom (kinda skimmed past them, earlier... sorry). Why shouldn't I use Last as my variable? I find it makes my scripts cleaner to read...

Dupe will identify the first blended frame. I then use 5 conditional statements (one for each possible location of the blended frame in a 5 frame set), where each one will use Interleave () and SelectEvery () to keep the 3 good frames, and insert the unblended frame.
__________________
I'm a boxer who can Bob () & Weave (). I like to Overlay () punches and Blur () his vision to ShowFiveVersions (). My KO punch will always Pulldown ().TimeStretch () and all he will hear is Tone ().

Last edited by actionman133; 20th December 2005 at 16:45.
actionman133 is offline   Reply With Quote
Old 20th December 2005, 16:47   #4  |  Link
foxyshadis
ангел смерти
 
foxyshadis's Avatar
 
Join Date: Nov 2004
Location: Lost
Posts: 9,556
Didée forgot, but all your access to the variables must be inside a FrameEvaluate or ScriptClip. Eval won't work; in this case:

frameevaluate(clp,"global Dupe = min(ab,bc,cd,de,ea)")
which must be above the frameevaluates.

I'm using the MinMax plugin, much easier than redoing the 5-way minimum in script.

All that said, MOmonster and I already wrote a function that accurately unblends double-blended telecine, my old one actually used the same philosophy (local minimum in unblended difference) but MOmonster's extends it considerably.

Now if you have triple-blended video, or different blend-weights, that's a different and rather more evil beast.

Last is a bad idea because it's a predefined variable: The last function result that isn't explicitly assigned to a variable.

Edit: I see, a straight min isn't quite what you needed, you wanted the index. Well, you could either use a lot of nested () > ? :, or find a plugin, I'd help but I have to leave. ^^;;

Last edited by foxyshadis; 20th December 2005 at 16:53.
foxyshadis is offline   Reply With Quote
Old 20th December 2005, 16:54   #5  |  Link
Didée
Registered User
 
Join Date: Apr 2002
Location: Germany
Posts: 5,389
Quote:
Originally Posted by actionman133
Thanks, the script is running now, except it's not working properly. The Framevaluate seems to not work as all the values are returned as 0.000000.
Ah, of course. You have to put all of those "Dupe" evaluations into conditional environment, too. If these are outside like they're now, they only hold the startup values from the time of script loading ...

Code:
# Find the frame which had the lowest difference in the two tests
x99 = FrameEvaluate(clp, """Dupe = (Eval (Dupe) > ea) ? "ea" : Dupe""")
x03 = FrameEvaluate(x99, """Dupe = (Eval (Dupe) > de) ? "de" : Dupe""")
x02 = FrameEvaluate(x03, """Dupe = (Eval (Dupe) > cd) ? "cd" : Dupe""")
x01 = FrameEvaluate(x02, """Dupe = (ab > bc) ? "bc" : "ab" """)
Plus you have to make "Dupe" a global, too.

Still, you need to actually do something with the result for "Dupe" ... and you have to do it in the conditional environment.


/*participating in the "edit" mess*/

Oh, Evaluate doesn't work in Conditional Env.? Didn't know ... in fact I never have tried that.
__________________
- We´re at the beginning of the end of mankind´s childhood -

My little flickr gallery. (Yes indeed, I do have hobbies other than digital video!)

Last edited by Didée; 20th December 2005 at 16:57.
Didée is offline   Reply With Quote
Old 1st January 2006, 14:28   #6  |  Link
actionman133
Movie buff & shine
 
Join Date: Jan 2004
Location: Logan, the only hole above ground.
Posts: 257
Update!

I've worked on this filter some more and it's almost complete. It works beautifully for about the first 600 frames of my test clip, then starts mishapping. I know it's not the video fooling my script because if I trim into the clip a little, previously mismatched frames are suddenly deblended correctly. The script and my test clip are online at this page:

http://actionman133.isa-geek.net:8080/blended.html

Here is the script: (I know Didee said I shouldn't use LAST, but honestly, I can't read or write a script without using it... sorry)


Code:
AVISource ("Blended.avi")
DeBlend ()

Function DeBlend (clip Last, bool "Debug") {

  # Declarations
Debug = Default (Debug, False)
Global Original = Last

  # Test each frame for deblending matches.
Global a = Subtract (Last, Trim (1, 0).Levels (0, 1, 255, 128, 255, False)).Levels (0, 1, 127, 0, 255, False).Trim (1, 0)
Global b = Subtract (Levels (0, 1, 255, 0, 127, False), Trim (1, 0)).Levels (0, 1, 127, 255, 0, False).DuplicateFrame (0)
Global Unblended = Merge (a, b)	# Use this as higher quality replacement in final clip
Global Diff = Subtract (a, b)


  # Perform Deblending on best matches, also decimates 5 frames to 4
ScriptClip (Original, """\
	(Dupe == "ab") ? Interleave (Unblended.SelectEvery (5, 0), Original.SelectEvery (5, 2), Original.SelectEvery (5, 3), Original.SelectEvery (5, 4)) : \
	(Dupe == "bc") ? Interleave (Original.SelectEvery (5, 0), Unblended.SelectEvery (5, 1), Original.SelectEvery (5, 3), Original.SelectEvery (5, 4)) : \
	(Dupe == "cd") ? Interleave (Original.SelectEvery (5, 0), Original.SelectEvery (5, 1), Unblended.SelectEvery (5, 2), Original.SelectEvery (5, 4)) : \
	(Dupe == "de") ? Interleave (Original.SelectEvery (5, 0), Original.SelectEvery (5, 1), Original.SelectEvery (5, 2), Unblended.SelectEvery (5, 3)) : \
	(Dupe == "ea") ? Interleave (Original.SelectEvery (5, 0), Original.SelectEvery (5, 1), Original.SelectEvery (5, 2), Original.SelectEvery (5, 3)) : \
Last""").\
AssumeFPS (Original.Framerate () * 0.8, False).Trim (0, Round ((Original.Framecount () + 1) * 0.8) - 1)


  # Find frame with least difference between a & b in every 5 frames
FrameEvaluate ("""Dupe = (Eval (Dupe) < ea) ? Dupe : "ea" """)
FrameEvaluate ("""Dupe = (Eval (Dupe) < de) ? Dupe : "de" """)
FrameEvaluate ("""Dupe = (Eval (Dupe) < cd) ? Dupe : "cd" """)
FrameEvaluate ("""Dupe = (ab < bc) ? "ab" : "bc" """)


  # Find differences between a & b for each frame
FrameEvaluate ("ea = YPlaneMinMaxDifference (Diff.SelectEvery (5, 4))")
FrameEvaluate ("de = YPlaneMinMaxDifference (Diff.SelectEvery (5, 3))")
FrameEvaluate ("cd = YPlaneMinMaxDifference (Diff.SelectEvery (5, 2))")
FrameEvaluate ("bc = YPlaneMinMaxDifference (Diff.SelectEvery (5, 1))")
FrameEvaluate ("ab = YPlaneMinMaxDifference (Diff.SelectEvery (5, 0))")


  # Create Debugging clip
Global Match = "% Similar"
Top = StackHorizontal (Original, ScriptClip (Diff, "Subtitle (String (Round ((255 - YPlaneMinMaxDifference ()) / 2.55)) + Match)"))
Bottom = StackHorizontal (a, b)
Info = StackVertical (Top, Bottom)

Return (Debug == True) ? Info : Last

}
__________________
I'm a boxer who can Bob () & Weave (). I like to Overlay () punches and Blur () his vision to ShowFiveVersions (). My KO punch will always Pulldown ().TimeStretch () and all he will hear is Tone ().
actionman133 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 06:27.


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