Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #14638 > unrolled thread
| Started by | Dangling Pointer <dpointer2@gmail.com> |
|---|---|
| First post | 2012-05-18 22:58 -0700 |
| Last post | 2012-05-20 11:59 -0500 |
| Articles | 9 — 5 participants |
Back to article view | Back to comp.lang.java.programmer
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
| From | Dangling Pointer <dpointer2@gmail.com> |
|---|---|
| Date | 2012-05-18 22:58 -0700 |
| Subject | Bicubic 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]
| From | Roedy Green <see_website@mindprod.com.invalid> |
|---|---|
| Date | 2012-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]
| From | Roedy Green <see_website@mindprod.com.invalid> |
|---|---|
| Date | 2012-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]
| From | "John B. Matthews" <nospam@nospam.invalid> |
|---|---|
| Date | 2012-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]
| From | Dangling Pointer <dpointer2@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Dangling Pointer <dpointer2@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Jan Burse <janburse@fastmail.fm> |
|---|---|
| Date | 2012-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]
| From | "John B. Matthews" <nospam@nospam.invalid> |
|---|---|
| Date | 2012-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]
| From | BGB <cr88192@hotmail.com> |
|---|---|
| Date | 2012-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