Scaling of EWA Lanczos function with non-standard window

Discuss digital image processing techniques and algorithms. We encourage its application to ImageMagick but you can discuss any software solutions here.
Locked
nand
Posts: 9
Joined: 2015-02-23T13:07:43-07:00
Authentication code: 6789

Scaling of EWA Lanczos function with non-standard window

Post by nand »

EDIT: Never mind, I figured it out. Annotations in bold.

Hey,

I'm trying to implement EWA Lanczos rescaling in my application, and I'm trying to figure out what the best way to do this is. For starters, the underlying problem is that the true radius of the function (at 3 taps) is something like 3.238 instead of 3.0, so we need to consider all source values up to and including those at that distance from the pixel.

Since we use a rectangular pixel array, this means that I will potentially have to include all of the pixel values of radius 4 in my search space, since the weight might be non-zero for anything between radius 3 and radius 4 - that is, the algorithm iterates over all 8x8 = 64 values, instead of only needing to consult 3x3 = 36 values. This is quite a bad performance hit, so I'm thinking about ways to avoid it. I can avoid it almost entirely by adding a simple check to see if the distance is greater than the position. That check is surprisingly efficient on the GPU, even though it's a conditional branch. So this problem is already sort of solved.

One of the things I tried in my search is to simply window the function differently - that is, use jinc(x) * jinc(x * jinc_zeros[0] / taps) instead of the traditional jinc(x) * jinc(x * jinc_zeros[0] / jinc_zeros[taps-1]).

This crude hack makes the function reach 0 at 3.0 instead of 3.22, because the window is smaller. However, this changes the function's properties - it loses some of its visual quality (not sure how to describe it), and it also no longer blurs hash patterns as strongly.

I then wondered if I could simply change the scaling of the first term as well, to make them line up again. In essence, this is what your LanczosRadius does. The natural conclusion would be to scale it so that it reaches 0 at 3.0 as well, that is: jinc(x * jinc_zeros[taps-1] / taps) * jinc(x * jinc_zeros[0] / taps). However, this particular scaling works less well than intended - it also doesn't blur hash patterns, for example. I have found an alternative scaling value, that is a value of c such that jinc(x / c) / jinc(x * jinc_zeros[0] / taps) produces a similar result (blurred hash pattern, visual quality) to the true Lanczos function, but I can't figure out where it comes from: I'm using approximately 1.05, which I've arrived at by trial and error (picking values until the hash pattern disappears almost completely). I was actually scaling *both* jinc functions, so it was really jinc(x / c) / jinc(x * jinc_zeros[0] / taps / c) I was testing

Note that for other taps, this value changes. For 4 taps, I arrived at something like 1.20. I don't know where either of these two figures come from.

Can somebody help me figure this out? Is there perhaps another way to compute EWA Lanczos3 more efficiently than by consulting a 8x8 matrix of pixels? Is it possible to use something like a bilinear lookup to reduce this to 4x4? (I know the technique works when the weight matrix is strictly positive, but I'm not sure if it does for weight functions that reach negative values)
Last edited by nand on 2015-02-23T15:41:44-07:00, edited 1 time in total.

nand
Posts: 9
Joined: 2015-02-23T13:07:43-07:00
Authentication code: 6789

Re: Scaling of EWA Lanczos function with non-standard window

Post by nand »

Update: I've modified my algorithm to support a fractional radius in an efficient way, so I can actually plug in the true radius of 3.2383154841662362 and see the results.

Curiously enough, this still does not remove a hash pattern completely, even when using the “true” formula: jinc(x) * jinc(x * jinc_zeros[0] / 3.238...). I'm wondering if this is an indication of some other bug in my algorithm or not.

I have taken some example images. The input is this file: http://www.imagemagick.org/Usage/filter/hash.png
In each example, I am scaling using exactly this function as kernel: jinc(x) * jinc(x * 1.2196698912665045 / radius)

radius=3.000: https://i.imgur.com/It2rd2N.png
radius≈3.238: https://i.imgur.com/c1pW656.png

As you can see, the hash pattern is made less distinct, but it is not gone completely. Is this normal?

nand
Posts: 9
Joined: 2015-02-23T13:07:43-07:00
Authentication code: 6789

Re: Scaling of EWA Lanczos function with non-standard window

Post by nand »

How odd; I found that by blurring it *very* slightly (blur factor = 1.01), I got the hash pattern to go away entirely:

radius≈3.238 blur=1.01: https://i.imgur.com/YzLMdfk.png

ImageMagick seems to replicate this result. It gets even closer with blur=1.015, too. I wonder what the significance of this, if any, is.

Locked