View Full Version : Attempt for new IVTC
actionman133
10th January 2006, 13:59
With the spare time Christmas holidays have granted me, I've started an IVTC filter based on a concept that (to my knowledge) has not been employed yet, although it is similar to SmartDecimate.
This is it's theory of operation, and I will use this Jpeg as a visual guide...
http://actionman133.isa-geek.net:8080/avs/avs.html (http://actionman133.isa-geek.net:8080/avs/avs.jpg)
The Jpeg is a collection of five consecutive frames that have undergone DoubleWeave () on an NTSC DVD clip (specifically, the music DVD that came with the Revenge of the Sith soundtrack, chosen because of it's hardcoded telecine). I'll refer to the various frames by their subtitled numbers from now on.
First thing to note. At least one of frame 0 or frame 1 must be progressive. If frame 0 is progressive, then either 2 or 3 is progressive. If frame 1 is the progressive frame, then either 3 or 4 is progressive. By selecting the best two frames (0/1, then 2/3 or 3/4) from five, 24p is automatic.
What I've written so far works perfectly in it's execution process, but the field matching needs work. Particularly when the image moves up or down slowly, I get many false matches. I tried using LumaDifference between the fields and YPlaneMinMaxDifference on a clip that uses Subtract on the fields. Neither have managed to come close matching Telecide's success (even when using guide = 0), so I'm wondering what Mr Graft used for his field matching.
The script is also on the link I mentioned above. Anyone know how Telecide matches so effectively? Thanks.
neuron2
10th January 2006, 14:42
Anyone know how Telecide matches so effectively? Go to the following link and look at the entry for 5-26-2003.
http://neuron2.net/journal/journal2003.html
Read the previous entries for explanation of the notation. For the actual implementation, refer to the Decomb source code.
Mug Funky
10th January 2006, 14:54
function blindmatch (clip c)
{
global c = c
global swapped = c.doubleweave().selectodd()
global cmetric = c.yv12convolution(horizontal="1",vertical="-1 2 -1")
global smetric = swapped.yv12convolution(horizontal="1",vertical="-1 2 -1")
scriptclip(c,"cmetric.averageluma > smetric.averageluma? swapped : c")
}
this works in principle, but is kinda slow, and probably needs a more sophisticated convo filter to prevent false matches from slow vertical motion (though it's pretty solid as is).
actionman133
10th January 2006, 15:43
Thank you Neuron2, that was exactly what I was looking for. I'll post the new script up when I've finished testing it. :)
actionman133
12th January 2006, 14:47
OK, here's my update. Still at the same page. An example using the script is also there.
http://actionman133.isa-geek.net:8080/avs/avs.html
Noted additions/changes:
1. The difference map is new since the last version I put up here. It's based on neuron2's method but slightly adjusted. Instead of shifting one field up a quarter of a line, and the other down a quarter of a line, I simply shifted the odd fields up half a scanline. Since this softens that field a little, I apply a blur to the even fields to help match them up.
2. It uses a 2-test process to determine which field match is better. It first tries it with maximum sensitivity ("YPlaneMinMaxDifference (0)"). If either match that it tests returns 255, ie. max out, it does a less sensitive test, with the Difference threshold set to 1. I do this because I've seen the low-motion test return incorrect results if one of the matches maxed out (usually happens on pattern breaks at scene changes).
3. Can't remember if this was in the earlier version, but I have deinterlacing support, when necessary. It's just bobbing at the moment, but using a string input and Eval (), that could become more versatile. Using the aforementioned difference map used for field matching, if the selected match is higher than a specified threshold, it deinterlaces the frame. This isn't entirely effective at the moment, because some obviously combed frames scrape through and it deinterlaces some progressive frames, too. I've looked at some of the other entries on neuron2's suggestion list... still thinking about it before implementation.
Suggestions are welcome, of course. And if anyone wants to test this with a clip at home, they are more than welcome.
ChiDragon
14th January 2006, 09:24
I'm getting two errors subtitled on the video: "MinMax: Image must be planar" and "I don't know what abTest means". Also, every frame still seems to be interlaced, but horribly pixellated. This is with some MPEG-2 animation opened through DGDecode's plugin.
actionman133
14th January 2006, 16:20
I'm getting two errors subtitled on the video: "MinMax: Image must be planar" and "I don't know what abTest means". Also, every frame still seems to be interlaced, but horribly pixellated. This is with some MPEG-2 animation opened through DGDecode's plugin.
ScriptClip and FrameEvaluate require the color format to be planar, ie YV12. You're not using ConvertToRGB/YUY2 are you? If it's not YV12, then it can't evaluate abTest, and therefore not perform IVTC (by the way, this should be used for film... I don't know how it would go with anime). The pixelation occurs because you're seeing a slightly distorted version of the clip used to test field matches. Enter YV12 video in and it should function... maybe not properly, but it should work without saying errors.
This is by no means error proof... more of just a proof of concept (and I realised it's still flawed)... back to the drawing board. :(
ChiDragon
14th January 2006, 19:33
DGDecode outputs YV12, and I'm not using any conversions. I noticed some internal to the function, though...
actionman133
15th January 2006, 01:38
Yes, but it converts back to YV12 before passing it through FrameEvaluate and ScriptClip... I don't know what's happening here... (it was working with my test clips... Star Wars music videos and Collateral Making-of)...
vBulletin® v3.8.5, Copyright ©2000-2012, Jelsoft Enterprises Ltd.