2

So my question is how to get 16 bit bufferedImage from ij.ImagePlus...? If am trying to get using ShortProcessor it change my signed image to unsigned so i am not getting original image...Thanks in advance can any one provide solution.

enter image description here

How ImageJ display 16 bit signed image in their viewer..and we only get 8 bit bufferedImage or 16 bit unsigned bufferedImage So how can i get 16 bit signed BufferedImage..?

Jay Thakkar
  • 699
  • 1
  • 8
  • 13
Kamlesh
  • 517
  • 3
  • 10
  • 28
  • 1
    How do you get a signed 16-bit image in an `ImagePlus`? To my knowledge, ImageJ only supports _unsigned_ 16-bit images. What does [`ImagePlus#getType()`](http://jenkins.imagej.net/job/ImageJ1-javadoc/javadoc/ij/ImagePlus.html#getType%28%29) return? – Jan Eglinger Apr 24 '14 at 13:53
  • 1
    @JanEglinger ImageJ supports calibration functions though, which can be used to "simulate" signed 16-bit data. What kamlesh0606 could do is get the unsigned BufferedImage back, then convert it to a signed BufferedImage by looping over the pixels. I'm too busy at the moment to write this up as a proper answer, though... – ctrueden Apr 25 '14 at 03:07
  • yes @ctrueden getting my question properly – Kamlesh Apr 25 '14 at 10:02
  • imagePlus.getCalibration().isSigned16Bit() i get true – Kamlesh Apr 25 '14 at 10:05
  • 1
    Hey I also facing the same problem...can any one give answer..? – Jay Thakkar Apr 25 '14 at 10:06

1 Answers1

1

ImageJ can represent a signed 16-bit type using a special Calibration function. The isSigned16Bit() method indicates when that specific calibration function is in use—it is a linear m*x+b calibration where m=1 and b=-32768; this can be seen in the ImageJ source code.

ImageJ provides a way to obtain a BufferedImage from an ImagePlus via the getImage() method. However, this always returns an 8-bit BufferedImage.

So the next approach is to create your own BufferedImage with type DataBuffer.TYPE_SHORT, which wraps the same short[] array that backs the original ImagePlus object. Unfortunately, due to ImageJ's internal representation of signed 16-bit data, the values will be off by a constant offset of 32768—e.g., a raw value of -444 will be stored in ImageJ's short[] array as 32324. Due to this fact, you must manually adjust all your values before wrapping as a BufferedImage.

Here is some example code:

import io.scif.gui.AWTImageTools;
...

final ImagePlus imp =
    IJ.openImage("http://imagej.net/images/ct.dcm.zip");

// get pixels array reference
final short[] pix = (short[]) imp.getProcessor().getPixels();
final int w = imp.getWidth();
final int h = imp.getHeight();
final boolean signed = imp.getCalibration().isSigned16Bit();

if (signed) {
    // adjust raw pixel values
    for (int i=0; i<pix.length; i++) {
        pix[i] -= 32768;
    }
}

// convert to BufferedImage
final BufferedImage image = AWTImageTools.makeImage(pix, w, h, signed);

For the actual conversion of short[] to BufferedImage, this code makes use of the SCIFIO library's AWTImageTools.makeImage utility methods. SCIFIO is included with the Fiji distribution of ImageJ. Alternately, it is only a few lines of code which would be easy to copy and paste from the routine in question.

ctrueden
  • 6,751
  • 3
  • 37
  • 69
  • i am doing same procedure but not getting original image.still not get clear image(in contrast with gray but in real require black) – Kamlesh Apr 28 '14 at 04:54
  • Inspect the resultant `BufferedImage`'s pixel values to be certain, but my guess is that the image colors are simply not scaled the way you expect, because it is a 16-bit image. Java does not autoscale `BufferedImage`s when painting them. – ctrueden Apr 28 '14 at 20:55
  • Okay I got it , but any way to show this image in Jdialog. – Jay Thakkar Jun 18 '14 at 10:17