Search code examples
javamultidimensional-arrayrgbpixel

Changing a 2D array of pixels to an image based on the labels of the pixels


I am trying to implement Connected Components Labeling and I am stuck on how to convert the labeled pixels (i.e pixels that belong to a component in an image) to a color (preferably random colors for each component).

I have an 2D array newPixels [][] which holds values of 0, which is the background color and my labels, which are values of 1, 4, 7, 10 Now what I want to do is convert the pixels that are labeled with the 1, 4, 7, 10 to different colors (diff color for pixels labeled 1, 4, etc.)

What I thought of doing

BufferedImage img = new BufferedImage(ewPixelsWidth,
            newPixelHeight, BufferedImage.TYPE_INT_RGB);

for(int i = 0; i < newPixelsWidth; i++){
   for(int j = 0; j < newPixelHeight; j++}

       set img.setRGB(i,j, newPixel[i][i])
}

However when implementing the above code the image I got was back was just black. Now is that because the numbers of the pixels are in decimal and need to be in hex? Or maybe the label number 1, 4, 7, 10 cannot be converted to a color?


Solution

  • The values 1...10 actually do represent different colors: These are different shades of blue, but so dark that it's nearly not distinguishable from black.

    Pixels in an image of type BufferedImage.TYPE_INT_RGB are represented as int values. These consist of 4 bytes. The last three bytes define the red, green and blue (R,G,B) components.

    Note that for an image of type BufferedImage.TYPE_INT_ARGB, the first byte would be the alpha component (opacity). For such an image, you'd also have to set the first byte to 255 - otherwise, the pixels would remain transparent.

    So these are your colors:

      RRGGBB
    0x000001
    0x000004
    0x000007
    0x000010
    

    A value like

    0x0000FF
    

    would be a fully saturated blue.


    In order to assign colors to pixels based on these values, it would be helpful to know how many colors you expect. One approach could be to just fill an array with random colors, and look them up later:

    int numColors = 10;
    int colors[] = new int[numColors];
    Random random = new Random(0);
    for (int i=0; i<numColors; i++) {
        colors[i] = 0xFF000000 | random.nextInt();
    }
    
    // In your loop:
    img.setRGB(i,j, colors[newPixel[i][i]]);
    

    Note that you cannot be sure that these random colors will be easily distinguishable. Alternatively, you can use some common color map. Examples can be found online, for example, at http://colorbrewer2.org/#type=qualitative&scheme=Paired&n=11 . Using these, you can directly define the colors array like that:

    int colors[] =
    {
        0xffa6cee3,
        0xff1f78b4,
        0xffb2df8a,
        0xff33a02c,
        0xfffb9a99,
        0xffe31a1c,
        0xfffdbf6f,
        0xffff7f00,
        0xffcab2d6,
        0xff6a3d9a,
        0xffffff99
    };