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 Development

Reply
 
Thread Tools Search this Thread Display Modes
Old 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.
tritical is offline   Reply With Quote
Old 15th September 2007, 03:01   #2  |  Link
Dark Shikari
x264 developer
 
Dark Shikari's Avatar
 
Join Date: Sep 2005
Posts: 8,689
Wow, that is a nice filter

Great work.
Dark Shikari is offline   Reply With Quote
Old 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.
Revgen is offline   Reply With Quote
Old 15th September 2007, 06:56   #4  |  Link
foxyshadis
ангел смерти
 
foxyshadis's Avatar
 
Join Date: Nov 2004
Location: Lost
Posts: 9,413
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().
__________________
There are four boxes to be used in defense of liberty: soap, ballot, jury, and ammo. Please use in that order.
foxyshadis is offline   Reply With Quote
Old 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.
tritical is offline   Reply With Quote
Old 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 View Post
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.
Revgen is offline   Reply With Quote
Old 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
tritical is offline   Reply With Quote
Old 15th September 2007, 10:34   #8  |  Link
scharfis_brain
brainless
 
scharfis_brain's Avatar
 
Join Date: Mar 2003
Location: Germany
Posts: 3,607
@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.
scharfis_brain is offline   Reply With Quote
Old 15th September 2007, 13:17   #9  |  Link
scharfis_brain
brainless
 
scharfis_brain's Avatar
 
Join Date: Mar 2003
Location: Germany
Posts: 3,607
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.
scharfis_brain is offline   Reply With Quote
Old 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.
tritical is offline   Reply With Quote
Old 15th September 2007, 16:48   #11  |  Link
scharfis_brain
brainless
 
scharfis_brain's Avatar
 
Join Date: Mar 2003
Location: Germany
Posts: 3,607
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.
scharfis_brain is offline   Reply With Quote
Old 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.
tritical is offline   Reply With Quote
Old 15th September 2007, 18:24   #13  |  Link
Chainmax
Huh?
 
Chainmax's Avatar
 
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.
Chainmax is offline   Reply With Quote
Old 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?
MfA is offline   Reply With Quote
Old 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.
tritical is offline   Reply With Quote
Old 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.
Revgen is offline   Reply With Quote
Old 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)
tritical is offline   Reply With Quote
Old 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 View Post
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.
Revgen is offline   Reply With Quote
Old 15th September 2007, 23:59   #19  |  Link
scharfis_brain
brainless
 
scharfis_brain's Avatar
 
Join Date: Mar 2003
Location: Germany
Posts: 3,607
@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.
scharfis_brain is offline   Reply With Quote
Old 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.
Revgen is offline   Reply With Quote
Reply

Tags
deinterlace, nnedi

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 05:47.


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