Skip to main content

JPEG2000 Lossy with strange tiling artifacts - JAI/IO

7 replies [Last post]
lafrad
Offline
Joined: 2005-04-29

I am trying to shrink Medical CT images, extracted from dicom files (that part is already done), by using JPEG2000 Lossless compression. I currently do this using the following code:

---------------
ImageWriter jp2iw = (ImageWriter)iter.next();

IIOImage iioImage = new IIOImage(image, null, null);

J2KImageWriteParam writeParam = new J2KImageWriteParam();

double encodingRate = (double)bitsS / 15.0d;

writeParam.setLossless(false);
writeParam.setEncodingRate(encodingRate);

int [] codeblockSize = new int[]{128, 8};

writeParam.setCodeBlockSize(codeblockSize);
writeParam.setTilingMode(ImageWriteParam.MODE_DISABLED);
writeParam.setProgressionType("res");

ImageOutputStream ios = new FileImageOutputStream(imageFile);

jp2iw.setOutput(ios);

jp2iw.write(null, iioImage, writeParam);

------------------------------

This creates noticeably smaller images, yet the quality remains good, (of course).

The problem is, every once in a while (about 1% of the images I create) , there is an image with "snow" in a "tile" of the image.

The snow appears in all image types: RGB, Grayscale, 8-bit, 12-bit, 16-bit, and 24-bit images. Is there a method that I should be setting somewhere? Is there a better technique to be creating these lossy images?

Thanks,
Mike

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Brian Burkhalter

On Fri, 1 Jul 2005 jai-interest@javadesktop.org wrote:

> Ok. Figured out a way to get the "java only" JPeg 2000 decoder. its a hack for now, but it does the trick:
>
> --------------------
> Iterator iter = ImageIO.getImageWritersBySuffix(imageFormat);
>
> if(iter.hasNext())
> {
> iter.next();
> ImageWriter jp2iw = (ImageWriter)iter.next();
>
> IIOImage iioImage = new IIOImage(image, null, null);
>
> --------------------
>
> Basically, I skip the "first" Image writer given to me by ImageIO, and use the second one.

The writers should always be returned with the native one having priority over
the Java one.

> Somehow, the "DLL" version does NOT represent 12 and 16 bit grayscale images the same way as the "Java" version does. Images encoded with the "Java version" and viewed with the "DLL" version are really dark, (REALLY). Images encoded with the "DLL" version and then opened with the "Java" version are really BRIGHT. (it makes sense). This ONLY occurs on 12 and 16 bit images. All of my 8 bit grayscale 24-bit RGB are visually identical (Its a lossy codec, so they might not be exactly the same.. but its impossible to tell with the eye)

This might be related to the discussion thread "Problem saving 12-bit ushort
jpeg2000". Apparently for ComponentSampleModel data the bit depth is always
written as a multiple of 8.

> Also, the "Java" only version of the codec seems to really loose a lot of image quality on 12 and 16 bit images. Using an identical encoding rate on the 12-bit image results in a very poor, blurry image (the color intensity IS in the correct range though).
>
> Am I understanding the encoding rate incorrectly?

Encoding rate is (for a single band image) the number of bits in the
compressed data stream divided by the product of the image dimensions
(width*height), insofar as I understand it.

For the foregoing two problems (12 and 16 bits on native versus Java and
image quality on Java) it would be most helpful if you would provide (a)
test case(s) and data as needed with which we could reproduce the
problem(s). These could be supplied as part of (an) issue report(s) submitted
here:

https://jai-imageio-core.dev.java.net/servlets/ProjectIssues

Thanks,

Brian

----------------
Brian Burkhalter
Advanced Development/Media & Entertainment
Market Development Engineering
Sun Microsystems, Inc.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This email message is for the sole use of the intended recipient(s)
and may contain confidential and privileged information. Any
unauthorized review, use, disclosure or distribution is prohibited.
If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net

choco
Offline
Joined: 2005-07-06

Hi there.

We're trying using jai to compress DICOM ram images into jpeg 2000 lossy format. When compressing images of 12-bits-MONOCROM format ,the output images will be covered by strange "grid" (or strange tiling artifacts ,you may say). But if we doing the same thing on 24-bits-RGB format ,it goes fine.

If we set jpeg 2000 lossy mode to jpeg 2000 lossless mode,both 12bits MONO and 24bits RGB output images are perfect.

My question is that,does jai supports 12 bits jpeg 2000 lossy compression?

ps. our develop environments are JDK1.4.2_08 with JAI 1.1.3 installed.

Regards,
Choco

Brian Burkhalter

Mike,

Do you know whether you are using the native or the java plug-in (check the
fully qualified name of the reader-writer classes)? You might want to try
suppressing the native plug-in like this

java -Dcom.sun.media.imageio.disableCodecLib=true ...

to see whether it makes any difference.

Brian

On Thu, 30 Jun 2005 jai-interest@javadesktop.org wrote:

> I am trying to shrink Medical CT images, extracted from dicom files (that part is already done), by using JPEG2000 Lossless compression. I currently do this using the following code:
>
[...]
>
> This creates noticeably smaller images, yet the quality remains good, (of course).
>
> The problem is, every once in a while (about 1% of the images I create) , there is an image with "snow" in a "tile" of the image.
>
> The snow appears in all image types: RGB, Grayscale, 8-bit, 12-bit, 16-bit, and 24-bit images. Is there a method that I should be setting somewhere? Is there a better technique to be creating these lossy images?

----------------
Brian Burkhalter
Advanced Development/Media & Entertainment
Market Development Engineering
Sun Microsystems, Inc.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This email message is for the sole use of the intended recipient(s)
and may contain confidential and privileged information. Any
unauthorized review, use, disclosure or distribution is prohibited.
If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net

lafrad
Offline
Joined: 2005-04-29

Heh.. I tried that, but then the initial read of image from the dicom fails:

--------------------------------------------
javax.imageio.IIOException: Unsupported JPEG process: SOF type 0xc3
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImageHeader(Native Method)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readNativeHeader(JPEGImageReader.java:554)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.checkTablesOnly(JPEGImageReader.java:309)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.gotoImage(JPEGImageReader.java:431)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readHeader(JPEGImageReader.java:547)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:880)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:864)
at javax.imageio.ImageIO.read(ImageIO.java:1400)
at javax.imageio.ImageIO.read(ImageIO.java:1322)
----------------------------------------------

I am going to try reading different formats for the input, but that really isn't a solution, as JPEG Lossless is a widely used compression method in the Medical world....

any more suggestions?

Message was edited by: lafrad

lafrad
Offline
Joined: 2005-04-29

More info: I am finding that this is occuring on the following Hardware/OS's:

Dell PE750 - 3.0 GHz
Fedora Core 3 - i386 - 32-bit
Java 1.5.0_03 32-bit
JAI - 1.1.2_01 - (downloaded binary)
JAI/IO - 1.0 - (downloaded binary)

Generic AMD64 2800+ -
Fedora Core 4 - x86_64 - 64-bit
Java 1.5.0_04 64-bit
JAI - 1.1.3_Alpha - (downloaded binary)
JAI/IO - 1.1_Alpha - (downloaded binary)

It occurs in all viewers also, (6 different machiens with different OS's/java versions all see the same corrupted image. Some have the native DLL's/Libraries installed, some dont.) The problem is definately on the compression end.

lafrad
Offline
Joined: 2005-04-29

Ok. Figured out a way to get the "java only" JPeg 2000 decoder. its a hack for now, but it does the trick:

--------------------
Iterator iter = ImageIO.getImageWritersBySuffix(imageFormat);

if(iter.hasNext())
{
iter.next();
ImageWriter jp2iw = (ImageWriter)iter.next();

IIOImage iioImage = new IIOImage(image, null, null);

--------------------

Basically, I skip the "first" Image writer given to me by ImageIO, and use the second one.

Good news is: The Java JJ2000 implementation does NOT create goofy "snowy" artificats when it creates the images. All of my images are a good representation of what an image file looks like.

Problems now are, Speed. JJ2000 seems to be abour 40% slower than the native DLL/Library installation. I could live with this, if necessary, on the servers. They are relatively powerful, and in the short term can handle the load. I CAN'T handle non-native libraries on our client computers. The images load too slow, and the user interface gets laggy.

Somehow, the "DLL" version does NOT represent 12 and 16 bit grayscale images the same way as the "Java" version does. Images encoded with the "Java version" and viewed with the "DLL" version are really dark, (REALLY). Images encoded with the "DLL" version and then opened with the "Java" version are really BRIGHT. (it makes sense). This ONLY occurs on 12 and 16 bit images. All of my 8 bit grayscale 24-bit RGB are visually identical (Its a lossy codec, so they might not be exactly the same.. but its impossible to tell with the eye)

Also, the "Java" only version of the codec seems to really loose a lot of image quality on 12 and 16 bit images. Using an identical encoding rate on the 12-bit image results in a very poor, blurry image (the color intensity IS in the correct range though).

Am I understanding the encoding rate incorrectly?

lafrad
Offline
Joined: 2005-04-29

Switching the filter to "lossless" makes all the problems go away. Both Methods, "Java" and "DLL" work flawlessly when I .setLossless(true)

Problem is, I am not saving any space then.