Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #14638 > unrolled thread

Bicubic interpolation suddenly is no better than bilinear.

Started byDangling Pointer <dpointer2@gmail.com>
First post2012-05-18 22:58 -0700
Last post2012-05-20 11:59 -0500
Articles 9 — 5 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  Bicubic interpolation suddenly is no better than bilinear. Dangling Pointer <dpointer2@gmail.com> - 2012-05-18 22:58 -0700
    Re: Bicubic interpolation suddenly is no better than bilinear. Roedy Green <see_website@mindprod.com.invalid> - 2012-05-18 23:12 -0700
      Re: Bicubic interpolation suddenly is no better than bilinear. Roedy Green <see_website@mindprod.com.invalid> - 2012-05-20 22:23 -0700
    Re: Bicubic interpolation suddenly is no better than bilinear. "John B. Matthews" <nospam@nospam.invalid> - 2012-05-19 07:26 -0400
      Re: Bicubic interpolation suddenly is no better than bilinear. Dangling Pointer <dpointer2@gmail.com> - 2012-05-19 08:07 -0700
        Re: Bicubic interpolation suddenly is no better than bilinear. Dangling Pointer <dpointer2@gmail.com> - 2012-05-19 09:13 -0700
          Re: Bicubic interpolation suddenly is no better than bilinear. Jan Burse <janburse@fastmail.fm> - 2012-05-19 20:48 +0200
          Re: Bicubic interpolation suddenly is no better than bilinear. "John B. Matthews" <nospam@nospam.invalid> - 2012-05-20 09:02 -0400
          Re: Bicubic interpolation suddenly is no better than bilinear. BGB <cr88192@hotmail.com> - 2012-05-20 11:59 -0500

#14638 — Bicubic interpolation suddenly is no better than bilinear.

FromDangling Pointer <dpointer2@gmail.com>
Date2012-05-18 22:58 -0700
SubjectBicubic interpolation suddenly is no better than bilinear.
Message-ID<d389e99e-2fc7-40dd-b07d-90140db4f380@w19g2000yqb.googlegroups.com>
For some reason, I'm suddenly seeing bilinear filtering when using
TYPE_BICUBIC filtering with AffineTransformOp in Java2D. This change
happened without my changing the Java version (1.6.0_24) being used!
What could be causing this, and how do I fix it?

[toc] | [next] | [standalone]


#14639

FromRoedy Green <see_website@mindprod.com.invalid>
Date2012-05-18 23:12 -0700
Message-ID<d9eer7ppi96umu526dpc6kanci6nd0hkgd@4ax.com>
In reply to#14638
On Fri, 18 May 2012 22:58:38 -0700 (PDT), Dangling Pointer
<dpointer2@gmail.com> wrote, quoted or indirectly quoted someone who
said :

>For some reason, I'm suddenly seeing bilinear filtering when using
>TYPE_BICUBIC filtering with AffineTransformOp in Java2D. This change
>happened without my changing the Java version (1.6.0_24) being used!
>What could be causing this, and how do I fix it?

You are claiming a "virgin birth" here.  Nothing charged, yet the
program gave different results.  What could possibly have changed?

Do you have two different jars? two different JVMs?  Some sort of
config file?  Is there any use of Random number generators in your
code?

Can your restore from backup and see the old behaviour, and then
compare files till you see what changed?
-- 
Roedy Green Canadian Mind Products
http://mindprod.com
"Plants" with "leaves" no more efficient than today's solar cells 
could out-compete real plants, crowding the biosphere with an
inedible foliage. Tough omnivorous "bacteria" could out-compete 
real bacteria: They could spread like blowing pollen, replicate 
swiftly, and reduce the biosphere to dust in a matter of days.
Dangerous replicators could easily be too tough, small, and 
rapidly spreading to stop -- at least if we make no preparation. 
We have trouble enough controlling viruses and fruit flies. 
~ Eric Drexler (born: 1955-04-25 age: 57)  
Engines of Creation: The Coming Era of Nanotechnology.
.

[toc] | [prev] | [next] | [standalone]


#14712

FromRoedy Green <see_website@mindprod.com.invalid>
Date2012-05-20 22:23 -0700
Message-ID<j9kjr71bpbgg8ikop6o87b23fj34cmdsr1@4ax.com>
In reply to#14639
On Fri, 18 May 2012 23:12:32 -0700, Roedy Green
<see_website@mindprod.com.invalid> wrote, quoted or indirectly quoted
someone who said :

>You are claiming a "virgin birth" here.  Nothing charged, yet the
>program gave different results.  What could possibly have changed?

You are aware that any time you change a constant, you must do a clean
compile to propagate the value to all classes.
-- 
Roedy Green Canadian Mind Products
http://mindprod.com
"Plants" with "leaves" no more efficient than today's solar cells 
could out-compete real plants, crowding the biosphere with an
inedible foliage. Tough omnivorous "bacteria" could out-compete 
real bacteria: They could spread like blowing pollen, replicate 
swiftly, and reduce the biosphere to dust in a matter of days.
Dangerous replicators could easily be too tough, small, and 
rapidly spreading to stop -- at least if we make no preparation. 
We have trouble enough controlling viruses and fruit flies. 
~ Eric Drexler (born: 1955-04-25 age: 57)  
Engines of Creation: The Coming Era of Nanotechnology.
.

[toc] | [prev] | [next] | [standalone]


#14643

From"John B. Matthews" <nospam@nospam.invalid>
Date2012-05-19 07:26 -0400
Message-ID<nospam-B8112C.07265719052012@news.aioe.org>
In reply to#14638
In article 
<d389e99e-2fc7-40dd-b07d-90140db4f380@w19g2000yqb.googlegroups.com>,
 Dangling Pointer <dpointer2@gmail.com> wrote:

> For some reason, I'm suddenly seeing bilinear filtering when using 
> TYPE_BICUBIC filtering with AffineTransformOp in Java2D. This change 
> happened without my changing the Java version (1.6.0_24) being used! 
> What could be causing this, and how do I fix it?

How is the AffineTransformOp constructed?

What is the result of getInterpolationType()?

-- 
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>

[toc] | [prev] | [next] | [standalone]


#14645

FromDangling Pointer <dpointer2@gmail.com>
Date2012-05-19 08:07 -0700
Message-ID<fcd6a322-426d-40c7-af97-f4bd62addd5e@h10g2000pbi.googlegroups.com>
In reply to#14643
On May 19, 7:26 am, "John B. Matthews" <nos...@nospam.invalid> wrote:
> In article
> <d389e99e-2fc7-40dd-b07d-90140db4f...@w19g2000yqb.googlegroups.com>,
>  Dangling Pointer <dpoint...@gmail.com> wrote:
>
> > For some reason, I'm suddenly seeing bilinear filtering when using
> > TYPE_BICUBIC filtering with AffineTransformOp in Java2D. This change
> > happened without my changing the Java version (1.6.0_24) being used!
> > What could be causing this, and how do I fix it?
>
> How is the AffineTransformOp constructed?
>
> What is the result of getInterpolationType()?

new AffineTransformOp (someAffineTransform,
AffineTransformOp.TYPE_BICUBIC).

3.

Believe me, I double-checked *everything* when I noticed lower output
quality than I expected. I eyeballed every line of code dealing with
those particular images ten times, added debugging prints asking
things for their getInterpolationType or other attributes, etc. One
test I ran was to vary the interpolation type; I got worse quality
with TYPE_NEAREST_NEIGHBOR and the exact same with TYPE_BILINEAR which
is made me think it was suddenly acting like Java 4 instead of Java 6.
Of course I threw in System.out.println(System.getProperty
"java.version") once I had that thought, but out popped "1.6.0_24".

In fact, the quality I get (with TYPE_BICUBIC and TYPE_BILINEAR) is
worse than I'd even expect with TYPE_BILINEAR.

Oh, and another thing I tried was using a RenderingHints object
instead of the integer type in the ato's constructor.
KEY_INTERPOLATION, VALUE_INTERPOLATION_BICUBIC of course. When that
had no effect I tried adding KEY_RENDERING, VALUE_RENDER_QUALITY to
that, which didn't change anything either. Meanwhile, using
Graphics.drawImage(img,x,y,w,h,null) instead of
AffineTransformOp.filter (after setting the Graphics's RenderingHints
to the same) results in the quality I get using AffineTransformOp with
TYPE_NEAREST_NEIGHBOR (regardless of the RenderingHints).

Obviously *some* condition has changed. And it is, at least in the
latter case, a "hint" rather than a "guarantee". Is there some
circumstance in which it will fall back on bilinear even when
rendering hints tell it the caller prefers bicubic and prefers quality
over speed? This is an offline render from a BufferedImage to a
BufferedImage with no screen drawing surfaces used.

I suppose I could fall back on Image.getScaledInstance with
SCALE_AREA_AVERAGING, if I don't mind jobs that took seconds taking
minutes and giving only the quality that TYPE_BILINEAR *used* to give
me ...

[toc] | [prev] | [next] | [standalone]


#14646

FromDangling Pointer <dpointer2@gmail.com>
Date2012-05-19 09:13 -0700
Message-ID<9d143d01-dcf4-4343-9477-3ffbcd3027e1@ra8g2000pbc.googlegroups.com>
In reply to#14645
Well, I can confirm that something's hinky. I've now tested
downsampling a fairly noisy 9600x5400 image to 1280x720 in each of the
following ways:

* With Photoshop, using bicubic resampling.
* With Java, using the process of repeatedly halving the size of the
  input with AffineTransformOp and then making the final rescale when
  the input is less than or equal to twice the size of the
  destination, and using each of:
  * TYPE_NEAREST_NEIGHBOR
  * TYPE_BILINEAR
  * TYPE_BICUBIC
  * RenderingHints with interpolation set to bicubic and render set
    to quality.
* With Java, using Graphics.drawImage and RenderingHints set to
  bicubic/quality
* With Java, using getScaledInstance with SCALE_AREA_AVERAGING

The results were:

Best quality: Photoshop and SCALE_AREA_AVERAGING are about on a par
and heads and shoulders above the rest.

Next: iterative rescaling using either TYPE_BILINEAR, TYPE_BICUBIC, or
RenderingHints bicubic/quality (three-way tie).

Then: iterative rescaling using TYPE_NEAREST_NEIGHBOR and drawImage
using bicubic/quality (two-way tie).

I'm no longer sure that there's a change from the earlier operation of
this particular Java install. On closer inspection of older outputs of
similar code, I don't see a quality difference with iterative
"bicubic" rescaling when the downsampling ratio and input noisiness
were comparable; the better results were from less-noisy input images
and/or larger downsampling ratios (e.g. a 64x48 thumbnail from a
4000x3000 TIF).

Still, something is wrong. Iterative BILINEAR rescaling is *supposed*
to achieve comparable quality to SCALE_AREA_AVERAGING, and bicubic is
supposed to run rings around BILINEAR for quality in turn. So
iterative BILINEAR should be as good as SCALE_AREA_AVERAGING and
iterative BICUBIC should be better still. Instead, they're equal to
each other and significantly worse than SCALE_AREA_AVERAGING.

On the positive side, SCALE_AREA_AVERAGING doesn't seem to be as slow
in Java 6 as it is reputed to be (possibly this reputation is based on
the performance of older versions). So I'll be using that for now.

[toc] | [prev] | [next] | [standalone]


#14649

FromJan Burse <janburse@fastmail.fm>
Date2012-05-19 20:48 +0200
Message-ID<jp8pt1$87p$1@news.albasani.net>
In reply to#14646
Dangling Pointer schrieb:
> Still, something is wrong. Iterative BILINEAR rescaling is*supposed*
> to achieve comparable quality to SCALE_AREA_AVERAGING, and bicubic is

Most probably your claim is wrong, even with the best
rounding in the world. We have ideally:

    x1 + .... + x2n     x1 + x2        x2n-1 + x2n
    --------------- =   -------        -----------
          2^n              2                2
                                 ....
                          -------------------
                                   2

Now a rounding function r(x/n) can be viewed as
an nummerator correction c(x/n) function:

     r(x/n) = (x + c(x/n)) / n

For /2 the nummerator correction is either -1 or 0
when you round down. So there might be a maximal
correction of -1 * 2^(n-1) in the first iteration of
bilinear. Then -1 * 2 * 2^(n-2) in the next iteration,
and so on: Total maximal correction:

      -n*2^(n-1)

For /2^n the numeration correction is somewhere
between -2^n+1 and 0 when you round down. So maximal
correction is:

     -2^n+1

When is the iteration correction by 2^n bigger
than the area correction? Lets make a little table:

n	-n*2^(n-1)	-2^n+1	diff	2^n
1	-1	-1	0	2
2	-4	-3	1	4
3	-12	-7	5	8
4	-32	-15	17	16
5	-80	-31	49	32
6	-192	-63	129	64
7	-448	-127	321	128

So I guess for 4 iteration we could eventually
construct an example where the error would be
at least one color value step, since the
maximal numerator correction difference is
then greater than the denumerator 2^n.

Let's give it a try:

Iterative:
3 0 1 0 0 1 0 3
1 0 0 1
0 0
0

Area:
3 0 1 0 0 1 0 3
1

Yes we have found an example where iterative is
different from area by one color pixel value step.

Bye

[toc] | [prev] | [next] | [standalone]


#14671

From"John B. Matthews" <nospam@nospam.invalid>
Date2012-05-20 09:02 -0400
Message-ID<nospam-CB7225.09024720052012@news.aioe.org>
In reply to#14646
In article 
<9d143d01-dcf4-4343-9477-3ffbcd3027e1@ra8g2000pbc.googlegroups.com>,
 Dangling Pointer <dpointer2@gmail.com> wrote:

> On the positive side, SCALE_AREA_AVERAGING doesn't seem to be as slow 
> in Java 6 as it is reputed to be (possibly this reputation is based 
> on the performance of older versions). So I'll be using that for now.

Thank you for reporting your (extensive) findings. It sounds like you
are aware, but for reference: The Perils of Image.getScaledInstance()

<http://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html>

The last time I encountered such resampling problems, it turned out
to be an artifact inserted earlier in my pipeline that only became 
apparent in a later stage. FWIW, I had good results from ImageJ's 
bicubic interpolation implementation. I needed both 8- and 16-bit 
versions, with endian control for the latter, and it proved easy to 
script.

I'm not sure it's relevant, but I've occasionally had to specify 
the platform renderer instead of Sun’s 2D renderer:

    if (System.getProperty("os.name").startsWith("Mac OS X")) {
        System.setProperty("apple.awt.graphics.UseQuartz", "true");
    }

-- 
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>

[toc] | [prev] | [next] | [standalone]


#14676

FromBGB <cr88192@hotmail.com>
Date2012-05-20 11:59 -0500
Message-ID<jpb7u5$lia$1@news.albasani.net>
In reply to#14646
On 5/19/2012 11:13 AM, Dangling Pointer wrote:
> Well, I can confirm that something's hinky. I've now tested
> downsampling a fairly noisy 9600x5400 image to 1280x720 in each of the
> following ways:
>
> * With Photoshop, using bicubic resampling.
> * With Java, using the process of repeatedly halving the size of the
>    input with AffineTransformOp and then making the final rescale when
>    the input is less than or equal to twice the size of the
>    destination, and using each of:
>    * TYPE_NEAREST_NEIGHBOR
>    * TYPE_BILINEAR
>    * TYPE_BICUBIC
>    * RenderingHints with interpolation set to bicubic and render set
>      to quality.
> * With Java, using Graphics.drawImage and RenderingHints set to
>    bicubic/quality
> * With Java, using getScaledInstance with SCALE_AREA_AVERAGING
>
> The results were:
>
> Best quality: Photoshop and SCALE_AREA_AVERAGING are about on a par
> and heads and shoulders above the rest.
>
> Next: iterative rescaling using either TYPE_BILINEAR, TYPE_BICUBIC, or
> RenderingHints bicubic/quality (three-way tie).
>
> Then: iterative rescaling using TYPE_NEAREST_NEIGHBOR and drawImage
> using bicubic/quality (two-way tie).
>
> I'm no longer sure that there's a change from the earlier operation of
> this particular Java install. On closer inspection of older outputs of
> similar code, I don't see a quality difference with iterative
> "bicubic" rescaling when the downsampling ratio and input noisiness
> were comparable; the better results were from less-noisy input images
> and/or larger downsampling ratios (e.g. a 64x48 thumbnail from a
> 4000x3000 TIF).
>
> Still, something is wrong. Iterative BILINEAR rescaling is *supposed*
> to achieve comparable quality to SCALE_AREA_AVERAGING, and bicubic is
> supposed to run rings around BILINEAR for quality in turn. So
> iterative BILINEAR should be as good as SCALE_AREA_AVERAGING and
> iterative BICUBIC should be better still. Instead, they're equal to
> each other and significantly worse than SCALE_AREA_AVERAGING.
>
> On the positive side, SCALE_AREA_AVERAGING doesn't seem to be as slow
> in Java 6 as it is reputed to be (possibly this reputation is based on
> the performance of older versions). So I'll be using that for now.



quick comment:
note that you are downsampling (and by a significant factor as well), 
whereas bicubic is a filter better suited for upsampling (if used 
directly for downsampling, the quality will be terrible).

the direction that the resampling is being done is fairly important for 
which filter is being used (for general purpose image resampling, it is 
typical to detect whether the image is being upsampled or downsampled, 
and select which filter is used based on this).


instead, what is needed is to use a filter which averages the samples 
for downsampling (this is the best "simple" option). hence, something 
more like SCALE_AREA_AVERAGING.

whereas, bicubic will likely give the best quality when upsampling the 
image to a higher resolution.


otherwise, if general purpose resampling is needed (where the same image 
can be used for either upsampling or downsampling at the same time, such 
as a texture in 3D rendering), one needs a filter such as trilinear or 
tricubic.

( decided to leave out a description of how to go about implementing a 
tricubic filter, as this is a little more advanced. )

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web