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.

 Doom9's Forum NNEDI - intra-field deinterlacing filter
 Register FAQ Calendar Search Today's Posts Mark Forums Read

 15th September 2007, 02:41 #1  |  Link tritical Registered User   Join Date: Dec 2003 Location: MO, US Posts: 999 NNEDI - intra-field deinterlacing filter Well, here is nnedi v1.3. It isn't perfect yet, but I think it definitely proves that this method can work well. A v2.0 is already in the works. The filter operation is pretty simple... it throws away one field of each input frame and then interpolates the missing pixels. There is a parameter called 'field' to control which field is kept and double vs same rate output (same as the field parameter in eedi2). Then there are boolean Y, U, and V parameters to control which planes are processed. This filter turned out to be pretty good for resizing as well (limited to powers of 2 enlargement). Using it for resizing is pretty easy... pointresize the height to 2x, use nnedi, rotate left or right, pointresize again, use nnedi a second time, etc... It is slightly more difficult for YUY2 because turnleft()/turnright() will mess up (blur/interpolate) the chroma. So you will need to use utoy() and vtoy() to pull the chroma planes out and then process each of the 3 clips separately. Example functions for 2x resizing: Code: ```function nnediresize2x(clip c, bool pY, bool pU, bool pV) { v = c.nnedi(dh=true,Y=pY,U=pU,V=pV).turnleft() v = v.nnedi(dh=true,Y=pY,U=pU,V=pV).turnright() return v } function nnediresize_YUY2(clip c) { cy = c cu = c.utoy() cv = c.vtoy() cy = nnediresize2x(cy,true,false,false) cu = nnediresize2x(cu,true,false,false) cv = nnediresize2x(cv,true,false,false) return ytouv(cu,cv,cy) } function nnediresize_YV12(clip c) { return nnediresize2x(c,true,true,true) }``` This will result in a shifted image, the direction being dependent on the rotations used. As an example, 4x enlargement of clown image from http://www.general-cathexis.com/interpolation.html. No pre or post processing. Any feedback is welcome, and thanks again to everyone who contributed cpu time . Last edited by tritical; 21st September 2007 at 00:26.
 15th September 2007, 03:01 #2  |  Link Dark Shikari x264 developer     Join Date: Sep 2005 Posts: 8,688 Wow, that is a nice filter Great work.
 15th September 2007, 05:44 #3  |  Link Revgen Registered User   Join Date: Sep 2004 Location: Near LA, California, USA Posts: 1,545 I decided to use it as a bob filter and compare it to other bob filters. Since I tend to encode sports, it's what I'm most interested in. Here's my interpretation: NNEDI: Very Good Quality, Terrible Stability MVBOB: Very Good Quality, Very Good Stability MCBOB: Best Quality, Best Stability NNEDI+TDeint: Good Quality, Good Stability NNEDI didn't allow too many stray interlaced lines to come in, but the video was flickering and jerking too much and wasn't stable. Pairing it with TDeint improved stability but allowed more stray interlacing artifacts in. If there are any suggestions on improving quality for the NNDI scripts, let me know. Here's my Lagarith sample. http://www.mediafire.com/?42y1jis3mbg NNDI Settings: NNDI = nnedi(field=3,y=true,u=true,v=true,threads=2,opt=0) NNEDI+TDeint = interp = nnedi(field=3,y=true,u=true,v=true,threads=2,opt=0) tdeint(mode=1,order=1,edeint=interp) MVBOB = Default MCBOB = Default __________________ Pirate: Now how would you like to die? Would you like to have your head chopped off or be burned at the stake? Curly: Burned at the stake! Moe: Why? Curly: A hot steak is always better than a cold chop. Last edited by Revgen; 15th September 2007 at 06:47.
 15th September 2007, 06:56 #4  |  Link foxyshadis ангел смерти     Join Date: Nov 2004 Location: Lost Posts: 9,564 nnedi is a replacement for eedi2, not a smart bob on its own. Swap it for eedi2 in mvbob and then compare it to eedi2's performance, using either securebob, mvbob, or mcbob as you prefer. Function NNEDIbob(clip Input) { Input.nnedi(Field = -2) AssumeFrameBased() GetParity(Input) ? AssumeTFF() : AssumeBFF() } Add this as type == 4 to SecureBob. Make it default if you want, currently eedi2 is. Same thing in mcbob, but the relevant line to change there is edibobbed = clp.EEDIbob().
 15th September 2007, 09:11 #5  |  Link tritical Registered User   Join Date: Dec 2003 Location: MO, US Posts: 999 As foxyshadis said, nnedi is just an interpolater like eedi2. It would never be able to beat a motion compensated or motion adaptive bobber on content with static logos and writing. Anyways, I noticed a bug which was causing the incorrect lines of the chroma planes to be kept in yv12 (yuy2 was fine). I modified the link above to point to version 1.1.
15th September 2007, 09:24   #6  |  Link
Revgen
Registered User

Join Date: Sep 2004
Location: Near LA, California, USA
Posts: 1,545
Quote:
 Originally Posted by foxyshadis nnedi is a replacement for eedi2, not a smart bob on its own. Swap it for eedi2 in mvbob and then compare it to eedi2's performance, using either securebob, mvbob, or mcbob as you prefer. Function NNEDIbob(clip Input) { Input.nnedi(Field = -2) AssumeFrameBased() GetParity(Input) ? AssumeTFF() : AssumeBFF() } Add this as type == 4 to SecureBob. Make it default if you want, currently eedi2 is. Same thing in mcbob, but the relevant line to change there is edibobbed = clp.EEDIbob().
Thanks. I'll do it tommorow.
__________________
Pirate: Now how would you like to die? Would you like to have your head chopped off or be burned at the stake?

Curly: Burned at the stake!

Moe: Why?

Curly: A hot steak is always better than a cold chop.

 15th September 2007, 09:41 #7  |  Link tritical Registered User   Join Date: Dec 2003 Location: MO, US Posts: 999 I bobbed your sample using yadif with nnedi for spatial prediction. Result: test.avi
 15th September 2007, 10:34 #8  |  Link scharfis_brain brainless     Join Date: Mar 2003 Location: Germany Posts: 3,642 @tritical: wow! I am really impatient right now, to see a yadif+nnedi.dll to implement it into mvbob. this should jield into a massive improvement in stability. __________________ Don't forget the 'c'! Don't PM me for technical support, please.
 15th September 2007, 13:17 #9  |  Link scharfis_brain brainless     Join Date: Mar 2003 Location: Germany Posts: 3,642 I tested nnedi now and found that it creates garbage with SSE. It works fine if I force it to use C-Code. __________________ Don't forget the 'c'! Don't PM me for technical support, please.
 15th September 2007, 16:28 #10  |  Link tritical Registered User   Join Date: Dec 2003 Location: MO, US Posts: 999 What is the script you're using, and what cpu does your computer have? c code and sse produce exactly the same results on my laptop and desktop.
 15th September 2007, 16:48 #11  |  Link scharfis_brain brainless     Join Date: Mar 2003 Location: Germany Posts: 3,642 Code: ```loadplugin("c:\x\nnedi.dll") avisource("60i-YUY2-Huffy.avi").assumetff() nnedi(opt=0, field=-2)``` the resulting image looks like this: (opt=2 also produces this result) when I set opt=1 I receive a pretty nice interpolated result: the source video is 640x480@29.97fps YUY2 converting it to YV12 results in the same weird image. I use an Athlon XP 2600+ (Barton Core) with an ASUS A7N8X-XE Mainboard and 2 Gigs of RAM. The source image looks like this: __________________ Don't forget the 'c'! Don't PM me for technical support, please.
 15th September 2007, 18:08 #12  |  Link tritical Registered User   Join Date: Dec 2003 Location: MO, US Posts: 999 scharfis, could you run [link removed] with debugview open to capture the output. It should show which sse routines aren't working correctly on your computer. The output log might get really big really fast. Last edited by tritical; 16th September 2007 at 20:05.
 15th September 2007, 18:24 #13  |  Link Chainmax Huh?     Join Date: Sep 2003 Location: Uruguay Posts: 3,103 The 4x enlargement look amazing, it's better than most results in that page and at least comparable to Zhao Xin-LI and LAD Decovolution . Great work, tritical! __________________ Read Decomb's readmes and tutorials, the IVTC tutorial and the capture guide in order to learn about combing and how to deal with it.
 15th September 2007, 20:17 #14  |  Link MfA Registered User   Join Date: Mar 2002 Posts: 1,075 BTW, what kind of downsampling (or rather PSF) are you optimizing for? Straight bilinear (box) like Aruzinsky?
 15th September 2007, 20:47 #15  |  Link tritical Registered User   Join Date: Dec 2003 Location: MO, US Posts: 999 yadifmod v1.0. I've had this for a while, but never got it together for release. It is the same as Fizick's port, except that spatial predictions are taken from a user supplied clip. Also, it is not an Avisynth_C plugin. It works with YV12 and YUY2 input. @MfA None really. The primary purpose of the filter is interpolation for deinterlacing not image enlargement. The training set for v1.0 consisted of 220 frames taken from about 30-35 dvd sources (many of them being anime, probably 5-10 were real life sources) and some random images. The filter simply learns to predict a pixel value given only the pixels in the opposite field surrounding its location. For v2.0 I am increasing it to ~250-270 frames. Most of the new ones are from real life images and test clips I found on the internet. There are some other internal changes being made for the next version as well. Last edited by tritical; 15th September 2007 at 20:52.
 15th September 2007, 21:14 #16  |  Link Revgen Registered User   Join Date: Sep 2004 Location: Near LA, California, USA Posts: 1,545 Just previewed both MVBob and MCBob with NNEDI and it looks pretty good so far looking at still frames. I exprimented with this line in MCBOB Code: ```# If requested, do additional PP via EEDI2 # ---------------------------------------- oweave.mt_merge(last,notstatic,luma=false,U=3,V=3) AssumeTFF() edisingle = eedi2().LanczosResize(ox,oy,0,-0.5,ox,2*oy+0.001,taps=3) edidouble = merge(SeparateFields().SelectEven().eedi2(field=1),SeparateFields().SelectOdd().EEDI2(field=0),0.5) (EdiPost==1) ? edisingle : \ (EdiPost==2) ? edidouble : last``` and changed it to Code: ```# If requested, do additional PP via NNEDI # ---------------------------------------- oweave.mt_merge(last,notstatic,luma=false,U=3,V=3) AssumeTFF() edisingle = nnedi() edidouble = merge(nnedi(field=1),nnedi(field=0),0.5) (EdiPost==1) ? edisingle : \ (EdiPost==2) ? edidouble : last``` It looked okay, but it didn't smooth jagged lines as well as the EEDI2 one, so I kept the former. I'll let you know more once they are fully encoded. __________________ Pirate: Now how would you like to die? Would you like to have your head chopped off or be burned at the stake? Curly: Burned at the stake! Moe: Why? Curly: A hot steak is always better than a cold chop.
 15th September 2007, 21:56 #17  |  Link tritical Registered User   Join Date: Dec 2003 Location: MO, US Posts: 999 Changing edisingle = eedi2().LanczosResize(ox,oy,0,-0.5,ox,2*oy+0.001,taps=3) to edisingle = nnedi() can't be right. eedi2 is taking in a frame and doubling the height. Whereas, nnedi is taking in the same frame, throwing out half the lines and then interpolating them. To get the height doubling behavior with nnedi you need to pointresize to 2x vertically prior to calling nnedi. It should be: edisingle = pointresize(width,2*height).nnedi().LanczosResize(ox,oy,0,-0.5,ox,2*oy+0.001,taps=3)
15th September 2007, 22:01   #18  |  Link
Revgen
Registered User

Join Date: Sep 2004
Location: Near LA, California, USA
Posts: 1,545
Quote:
 Originally Posted by tritical Changing edisingle = eedi2().LanczosResize(ox,oy,0,-0.5,ox,2*oy+0.001,taps=3) to edisingle = nnedi() can't be right. eedi2 is taking in a frame and doubling the height. Whereas, nnedi is taking in the same frame, throwing out half the lines and then interpolating them. To get the height doubling behavior with nnedi you need to pointresize to 2x vertically prior to calling nnedi. It should be: edisingle = pointresize(width,2*height).nnedi().LanczosResize(ox,oy,0,-0.5,ox,2*oy+0.001,taps=3)
Okay, I'll try that out then.
__________________
Pirate: Now how would you like to die? Would you like to have your head chopped off or be burned at the stake?

Curly: Burned at the stake!

Moe: Why?

Curly: A hot steak is always better than a cold chop.

 15th September 2007, 23:59 #19  |  Link scharfis_brain brainless     Join Date: Mar 2003 Location: Germany Posts: 3,642 @tritical: the special version of nnedi.dll you gave me for testing with debugview neither shows a correct result with opt=2 nor with opt=1. debugview's only (over and over repeated) message is this: [2876] findCluster doesn't match! however, your officially posted nnedi.dll works fine with opt=1. __________________ Don't forget the 'c'! Don't PM me for technical support, please.
 16th September 2007, 00:24 #20  |  Link Revgen Registered User   Join Date: Sep 2004 Location: Near LA, California, USA Posts: 1,545 Okay I've now looked at MVBob and MCBob, and it appears that NNEDI makes a definite difference on edges. With EEDI2 the edges display something I call "blur bubbles" on straight lines. Replacing EEDI2 with NNEDI seems to greatly reduce if not eliminate these artifacts. Here's an example of MVBob in it's regular state. Here's MVBob paired with NNEDI instead of EEDI2 The differences are hard to notice while in motion though. __________________ Pirate: Now how would you like to die? Would you like to have your head chopped off or be burned at the stake? Curly: Burned at the stake! Moe: Why? Curly: A hot steak is always better than a cold chop. Last edited by Revgen; 16th September 2007 at 00:27.

 Tags deinterlace, nnedi