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 non-ringing Lanczos scaling
 Register FAQ Calendar Search Today's Posts Mark Forums Read

 1st March 2009, 15:41 #1  |  Link madshi Registered Developer   Join Date: Sep 2006 Posts: 9,140 non-ringing Lanczos scaling Hey guys, anyone interested in non-ringing Lanczos4 scaling? Unfortunately I'm not an Avisynth developer, so I can only describe the algorithm, maybe someone else experienced with Avisynth can implement it. (Caution: The following explanation is targeted at developers who know how Lanczos scaling works inside.) --------------- First of all the contributors need to be sorted. The contributor which is nearest to the "center" (usually gets the highest weight) should be first in the list etc. The list should be sorted for distance to the center and not for weight. The sorted contributor list makes it easy to apply special processing to the "main contributors". Code: ```upscaling: main contributors = first 2 contributors in the sorted list downscaling: main contributors = first "trunc(scale ratio) + 1" contribs``` E.g. for 1.9x downscaling the main contributors are the first 2 contributors in the sorted list. For 2.0x downscaling the first 3. Now calculate each destination value by using the usual Lanczos4 scaling, but additionally calculate the lowest and highest values of the main contributors. If the calculated destination value lies outside of the main contributors' value range, make sure that the destination value is modified to fit into range. That is the main concept of the algorithm. Unfortunately it's not as easy as it sounds right now, because if you do this separately for X and Y scaling, there are sometimes some artifacts. Some of these can be avoided by keeping track (throughout the whole X + Y scaling process!) of the highest/lowest values of all main contributors which are used to calculate a destination value/pixel and to correct the destination pixels only after X + Y scaling is fully completed. Here are some samples (scaled up 4x) with normal vs. anti-ringing Lanczos4 scaling: Unfortunately the algorithm isn't perfect. Look at the "out of order" text, it looks better without the anti-ringing extra processing. Maybe someone has an idea on how to further improve the algorithm? But I think it's working quite well already as it is... Here is a bigger picture: http://madshi.net/lanczos/lanczos.rar
 1st March 2009, 15:49 #2  |  Link Guest Guest   Join Date: Jan 2002 Posts: 21,907 What's your source for this material? How is this different from LimitedSharpenFaster?
 1st March 2009, 16:12 #3  |  Link Didée Registered User   Join Date: Apr 2002 Location: Germany Posts: 5,393 It's the concept of LimitedSharpenFaster. The difference is that LSF first does its supersampling/resizing stuff with a standard lanczos or spline resizer, and the limiting comes after that. So, where the standard resizers do ring, there LSF will ring, too. A basic resizer by the same method: Code: `LanczosResize(dest_x,dest_y).Repair(Gaussresize(dest_x,dest_y,p=100),1)` __________________ - 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!)
1st March 2009, 16:50   #4  |  Link
Registered Developer

Join Date: Sep 2006
Posts: 9,140
Quote:
 Originally Posted by neuron2 What's your source for this material?
The original photos used for testing were downloaded somewhere from the internet.

Quote:
 Originally Posted by Didée A basic resizer by the same method: Code: `LanczosResize(dest_x,dest_y).Repair(Gaussresize(dest_x,dest_y,p=100),1)`
Hmmmmm... I didn't know the "Repair" filter. Seems that it uses the same concept, but it's not as well optimized for the specific case, I think. E.g. from what I've just read, "Repair" always compares 3x3 pixels. From my tests that's a good general purpose solution, but maybe not the best solution specifically for scaling. For upscaling I'm only comparing 2x2 pixels (those which are nearer to the "center"). For downscaling it can be more than 3x3 pixels, depending on the scale factor.

Or in short: The algorithm I described is custom tailored to "contributor" based resampling algorithms, by making use of the information in the contributor list. I think this should result in slightly superior quality because exactly those pixels are compared which are the main contributors to the final destination pixel. If we compare too many or not enough pixels, the algorithm should get a bit less effective (e.g. miss some ringing or misdetect ringing).

Maybe we should do some comparison tests?

One thing I'm wondering about: "LanczosResize.Repair" does appear to be rather similar to my suggestion. So why is it (seemingly) used rather rarely? At least from what I've read in the forums, many people complain about Lanczos ringing and I haven't ever seen "LanczosResize.Repair" being mentioned as a possible workaround.

1st March 2009, 17:54   #5  |  Link
Guest
Guest

Join Date: Jan 2002
Posts: 21,907
Quote:
Can't you remember where? I want to read more about the algorithm.

Also, where do I find the Repair filter?

Last edited by Guest; 1st March 2009 at 17:59.

1st March 2009, 18:30   #6  |  Link
Registered Developer

Join Date: Sep 2006
Posts: 9,140
Quote:
 Originally Posted by neuron2 Can't you remember where?
The black&white image is from here:

http://compression.ru/video/resampling/index_en.html

The other two crops are from a photo I downloaded from a digicam review site, so not related in itself to scaling in any way. The original photo I used for testing is contained in the RAR linked in the first post.

Quote:
 Originally Posted by neuron2 I want to read more about the algorithm.
Do you mean the general Lanczos algorithm? In that case you can check out either AviSynth's source code or "swscale.c/h" (libav).

Or do you mean the algorithm I described here? I've "invented" that algorithm myself. So there's no website I can point you to. But if you know how Lanczos works then the description in the first post of this thread should be easy enough to understand. If you have any questions, just let me know...

But it seems that the basic concept of my algorithm was already used by "Repair" und "LimitedSharpenFaster" before. So I didn't really find anything new. Maybe a little quality optimization of what already existed.

Quote:
 Originally Posted by neuron2 Also, where do I find the Repair filter?
It's part of the AviSynth package "RemoveGrain". If you download "RemoveGrain", there's a HTML documentation inside which explains how "Repair" works.

Last edited by madshi; 1st March 2009 at 18:32.

 1st March 2009, 18:51 #7  |  Link Didée Registered User   Join Date: Apr 2002 Location: Germany Posts: 5,393 The repair() method is pretty basic, yes. However, the main problem is one step deeper. The approach with clipping to not go beyond the limits of a given neighborhood has downsides. It prevents ringing/overshooting in those places where you don't want such. Yes. But it also prevents ringing/overshooting in those places where you do want it. Ouch#1. In both cases, the output signal is not smooth anymore, due to the possible clipping of the signal peaks. Ouch#2. Rule of thumb: you don't want overshoot on one-step gradients, but you do want overshoot on the center of two-step gradients. __________________ - 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!)
1st March 2009, 20:33   #8  |  Link
Guest
Guest

Join Date: Jan 2002
Posts: 21,907
Quote:
 Unfortunately I'm not an Avisynth developer, so I can only describe the algorithm, maybe someone else experienced with Avisynth can implement it.
How did you make screenshots of your algorithm if you could not implement it? You're really confusing me.

 1st March 2009, 21:43 #9  |  Link Fizick AviSynth plugger     Join Date: Nov 2003 Location: Russia Posts: 2,183 neuron2, he may be not Avisynth but for example Gimp developer... __________________ My Avisynth plugins are now at http://avisynth.org.ru and mirror at http://avisynth.nl/users/fizick I usually do not provide a technical support in private messages.
1st March 2009, 23:21   #10  |  Link
Registered Developer

Join Date: Sep 2006
Posts: 9,140
Quote:
 Originally Posted by Didée The repair() method is pretty basic, yes. However, the main problem is one step deeper. The approach with clipping to not go beyond the limits of a given neighborhood has downsides. It prevents ringing/overshooting in those places where you don't want such. Yes. But it also prevents ringing/overshooting in those places where you do want it. Ouch#1. In both cases, the output signal is not smooth anymore, due to the possible clipping of the signal peaks. Ouch#2.
Yeah, I see the problems, they do show as artifacts.

Quote:
 Originally Posted by Didée Rule of thumb: you don't want overshoot on one-step gradients, but you do want overshoot on the center of two-step gradients.
That makes sense. The problem for me is that the pixel right next to an edge usually fails the "is this part of a gradient?" check - because the edge is right next to it. And this pixel is in danger of ringing. I've tried to detect gradients, but all I tried looked worse than the rather simple "clip any out of range values" approach.

Quote:
 Originally Posted by neuron2 How did you make screenshots of your algorithm if you could not implement it? You're really confusing me.
Sorry about the confusion. I've my own Delphi based scaling implementation. I came up with an IMHO ok looking workaround for the ringing problem so although I can't offer an AviSynth solution I thought I'd at least share the exact algorithm I'm using, in case one of the AviSynth devs is interested...

 15th April 2009, 09:20 #11  |  Link tetsuo55 MPC-HC Project Manager   Join Date: Mar 2007 Posts: 2,317 This looks very interesting. Although the nr-lancsoz has some artifacting i find this less disturbing than the ringing caused by normal lanczos. I also find the words easier to read. So we actually have 3 problems right? *Ringing introduced by lanczos *Artifacting introduced by Ringing fix *Inability to handle gradients correctly. Would it be possible/doable to use some kind of 2 pass approach? 1. Analyse image (filter out gradients) 2. Prepass NR-Lancsoz 3. Prepass "gradient-lanczos" ? 4. Merge result 5. Compare to original image to fix artifacting Some expert could probably put all of this into 1 single pass...
15th April 2009, 10:46   #12  |  Link
Registered Developer

Join Date: Sep 2006
Posts: 9,140
Quote:
 Originally Posted by tetsuo55 *Ringing introduced by lanczos *Artifacting introduced by Ringing fix
Yes.

Quote:
 Originally Posted by tetsuo55 *Inability to handle gradients correctly.
Huh?

15th April 2009, 12:17   #13  |  Link
tetsuo55
MPC-HC Project Manager

Join Date: Mar 2007
Posts: 2,317
Quote:
Quote:
 Originally Posted by madshi That makes sense. The problem for me is that the pixel right next to an edge usually fails the "is this part of a gradient?" check - because the edge is right next to it. And this pixel is in danger of ringing. I've tried to detect gradients, but all I tried looked worse than the rather simple "clip any out of range values" approach.

15th April 2009, 12:34   #14  |  Link
Registered Developer

Join Date: Sep 2006
Posts: 9,140
Quote:
 Originally Posted by tetsuo55 Your post earlier:
This falls into the category "Artifacting introduced by Ringing fix". It's not a 3rd extra thing.

15th April 2009, 13:02   #15  |  Link
tetsuo55
MPC-HC Project Manager

Join Date: Mar 2007
Posts: 2,317
Quote:
 Originally Posted by madshi This falls into the category "Artifacting introduced by Ringing fix". It's not a 3rd extra thing.
Ahh i guess i misunderstood that a separate problem

 17th April 2009, 15:45 #16  |  Link unix_sansei Wreaking havoc for years     Join Date: Sep 2007 Location: LA Posts: 125 add more lobes to reduce ringing or program up the mitchell or catrom. Last edited by unix_sansei; 17th April 2009 at 15:49.
17th April 2009, 19:22   #17  |  Link
Registered Developer

Join Date: Sep 2006
Posts: 9,140
Quote:
 Originally Posted by unix_sansei add more lobes to reduce ringing
What!? Adding more lobes *increases* ringing.

Quote:
 Originally Posted by unix_sansei or program up the mitchell or catrom.
That's not the point of this thread. Mitchell is noticeable softer than Lanczos. And Catmull-Rom has a lot more aliasing than Lanczos.

 17th April 2009, 20:27 #18  |  Link Gavino Avisynth language lover   Join Date: Dec 2007 Location: Spain Posts: 3,425 Furthermore, Mitchell and Catmull-Rom are already available through BicubicResize.
17th April 2009, 22:12   #19  |  Link
unix_sansei
Wreaking havoc for years

Join Date: Sep 2007
Location: LA
Posts: 125
Quote:
 Originally Posted by madshi What!? Adding more lobes *increases* ringing. That's not the point of this thread. Mitchell is noticeable softer than Lanczos. And Catmull-Rom has a lot more aliasing than Lanczos.

that's what i say What?

the infinite sync or besselj(arg)/arg are mathematically ideal for sampling.

when you window them, chop off lobes, you get ringing. the ringing is because your weights are relatively large negative if you have a very limited number of lobes. the more lobes you have the less significant the ringing as the negative coefficients are much smaller.

Mitchell are softer but generally they don't ring. so balance whether the softer is better overall or ringing.

18th April 2009, 12:38   #20  |  Link
Registered Developer

Join Date: Sep 2006
Posts: 9,140
Quote:
 Originally Posted by unix_sansei the infinite sync or besselj(arg)/arg are mathematically ideal for sampling. when you window them, chop off lobes, you get ringing. the ringing is because your weights are relatively large negative if you have a very limited number of lobes. the more lobes you have the less significant the ringing as the negative coefficients are much smaller.
That goes contrary to anything I've read and seen. See here:

http://audio.rightmark.org/lukin/gra...house_more.htm

You will notice that the "Sinc filter" has more ringing than anything else. The "Sinc filter" may be theoretically ideal, but it still has the most ringing compared to any other filter. If you think that this is not true, why don't you post a comparison screenshot between Lanczos and infinite Sinc filtering? I'd love to see infinite Sinc filtering without ringing!

Quote:
 Originally Posted by unix_sansei Mitchell are softer but generally they don't ring. so balance whether the softer is better overall or ringing.
You seem to misunderstand the purpose of this thread. I didn't start this thread to get help in finding a filter which doesn't ring. The purpose of this thread is to discuss a specific algorithm I've found which allows to do Lanczos filtering without getting ringing. So talking about Mitchell is out of topic here...