> being new to the list, please forgive me if I've missed something, is
> the goal to match existing apps in general or just to match specific
> applications as a reference?

Hello!

In my opinion, the goal is firstmost to be 'right'.  So thanks for
your extra set of eyes. :)

Of course, sometimes it's hard to verify what 'right' is, so next best
is to settle for 'matches everything else out there'. :)

Even if we've gotten the filter kernel math correct, there's other
parts in the codepath that can lead to differing results.  Thus, it's
a really good sanity check to see how our results compare against
other implementations people may be using alongside OIIO.  In the case
of OIIO's maketx, the typical alternative would be txmake that ships
with prman.  So it made sense to see how our filtering results
compare.  Also, internally we have an image processing tool, Katana,
which we've trusted for a long time. So it also makes sense to compare
against that.

Are there any other applications, or known reference filtering
results, that you'd trust?  (I threw in imagemagick as well into the
comparison mix, as they have nice support for kernels and I was
curious how their tool performed.)   Maybe something more scientific,
such as matlab?

>
> I notice the definition for Lanczos3 for instance is not my expected
> windowing function which is something more like:
>
> sinc(position) * sinc(position / size)
>
> where size = 3 for a 3 lobed window.

I believe we are using your definition of lanczos3.  We've just
expanded it to the underlying implementation that calls 'sin', not
'sinc'.  See http://en.wikipedia.org/wiki/Lanczos_resampling, where
they list the expansion:
http://upload.wikimedia.org/math/0/9/e/09ec679a25f4b98dc7d2b8e5dd07a488.png

The math we're using is: src/libutil/filter.cpp

    static float lanczos3 (float x) {
        const float a = 3.0f;  // Lanczos 3 lobe
        x = fabsf(x);
        if (x > a)
             return 0.0f;
        if (x < 0.0001f)
            return 1.0f;
        const float m_pi = float (M_PI);
        const float m_piinv = 1.0f / m_pi;
        const float ainv = 1.0f/a;
        float pix = m_pi * x;
        return (a*m_piinv*m_piinv)/(x*x) * sinf(pix)*sinf(pix*ainv);
    }

Please let me know if you think we're in error.

> Also i wondered what the 'phase' of the filters does the
> implementation sample at - does it always results in all pixels being
> filtered when exactly halving/doubling, or does the filter only
> effectively sample at 0.0 and thus return a single sample for half the
> outputs? (Once I have it compiled, I can obviously run it to find out,
> there appears to be a lot of +/- 0.5s in the code and I'm not as good
> as the compiler :-).

These are where the lanczos3 function (as implemented above) is being
queried.  Note that we scale x by pi, so you can really think of this
as pi/4, 3pi/4, etc.

x 0.25 y 0.890067
x 0.75 y 0.27019
x 1.25 y -0.132871
x 1.75 y -0.0677913
x 2.25 y 0.0300211
x 2.75 y 0.00735591

-- Jeremy
_______________________________________________
Oiio-dev mailing list
Oiio-dev@lists.openimageio.org
http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org

Reply via email to