1

I am trying to save a depth map from Kinect v2 which should come out as grayscale but every time that I try to save it as JPG file using the type BufferedImage.TYPE_USHORT_GRAY literally nothing happens (No warning on screen or in the console).

I manage to save it if I use types BufferedImage.TYPE_USHORT_555_RGB or BufferedImage.TYPE_USHORT_565_RGB but instead of being grayscale it come as out blueish or greenish depth maps.

Find below the code sample:

short[] depth = myKinect.getDepthFrame();
int DHeight=424;
int DWidth = 512;
int dx=0;
int dy = 21;

BufferedImage bufferDepth = new BufferedImage(DWidth,  DHeight, BufferedImage.TYPE_USHORT_GRAY);

try {
    ImageIO.write(bufferDepth, "jpg", outputFileD);
} catch (IOException e) {
    e.printStackTrace();
}

Is there anything I am doing wrong to save it in grayscale? Thanks in advance

Alex Acquier
  • 43
  • 1
  • 7
  • 1
    I don't think the standard `ImageIO` JPEG plugin supports writing 16 bit (USHORT) samples. Note that `ImageIO.write(...)` returns a `boolean`. If the return value is `false`, then nothing is written. You should check this value, to get feedback for why nothing happens. The easiest fix would probably be to use a different format, one that supports 16 bit samples, like TIFF or PNG. – Harald K May 18 '18 at 07:42
  • 1
    PS: Even if the image was written correctly, the above code would not store the depth map, as there's simply no interaction between `depth` and `bufferDepth`. You probably have this in your real code, but it would make the problem clearer if you added it to the code sample. – Harald K May 18 '18 at 07:48
  • @HaraldK, Yes you are right it does return a false boolean value, is there anay alternative to ImageIO.write(...) ? – Alex Acquier May 21 '18 at 12:22
  • @HalraldK, TIFF does not give results but PNG return a a very dark depth map – Alex Acquier May 21 '18 at 13:19
  • Yes, given the above code, I would expect the image to be completely black (as already noted). A (now deleted) answer mentioned the range of values from Kinect using only 14 (?) bits. You either need to scale the values, or create the image with the correct range. – Harald K May 21 '18 at 14:15
  • I think it uses 16 bits myself, I do not know where this 14 bits business is coming from. What do you mean by scaling the value? Do you mean the same way it is done below? – Alex Acquier May 21 '18 at 16:06

1 Answers1

1

You have to assign your data (depth) to the BufferedImage (bufferDepth) first.

A simple way to do this is:

short[] depth = myKinect.getDepthFrame();
int DHeight = 424;
int DWidth = 512;
int dx = 0;
int dy = 21;

BufferedImage bufferDepth = new BufferedImage(DWidth, DHeight, BufferedImage.TYPE_USHORT_GRAY);

for (int j = 0; j < DHeight; j++) {
    for (int i = 0; i < DWidth; i++) {
        int index = i + j * DWidth;
        short value = depth[index];
        Color color = new Color(value, value, value);
        bufferDepth.setRGB(i, j, color.getRGB());
    }
}

try {
    ImageIO.write(bufferDepth, "jpg", outputFileD);
} catch (IOException e) {
    e.printStackTrace();
}
  • Hi @Yuri, I got an error running your code coming from the fact that the values of value are too big (should be maximum 255) – Alex Acquier May 21 '18 at 11:55
  • 1
    I have no idea what are the values in depth[], I was assuming that the values range from 0 to 255. But you can surely normalize those values. If you do know what is the maximum value you can do a simple math: short value = (depth[index] * 255) / maxValue; – Yuri Pourre May 21 '18 at 13:47