javacolorscolor-spacelab-color-space

How to reverse Java color transform from RGB to CIEXYZ / CIELAB


My ultimate goal is to convert RGB to CIELAB, do some color averaging, and then convert back. So my assumption is that if, due to runtime circumstances, there is only a single color input, i.e. no averaging, then the transform output should be the exact same as the RGB input, but this isn't the case.

The CIELAB colorspace uses an intermediate transform to CIEXYZ colorspace (which is part of the JDK). That transform appears to be non-reversible or lossy? Is this correct? Or is there something wrong with my assumptions or implementation? Should I be using another method to work with these colors?

Test and output below. Why aren't rgb and rgb2 the same color?

private static final ColorSpace CIEXYZ =ColorSpace.getInstance(ColorSpace.CS_CIEXYZ);    
@Test
    public void testCiexyz() {
        float[] rgb = new float[] {0.15686275f, 0.2f, 0.20784314f};
        LOGGER.debug("rbg: {}",rgb);
        float[] xyz = CIEXYZ.fromRGB(rgb);
        LOGGER.debug("xyz: {}",xyz);
        float[] rgb2 = CIEXYZ.toRGB(xyz);
        LOGGER.debug("rbg2: {}",rgb2);
    }

Output

    09:46:59.762 [main] DEBUG org.phomos.sampler.ColorTest - rbg: [0.15686275, 0.2, 0.20784314]
        09:46:59.875 [main] DEBUG org.phomos.sampler.ColorTest - xyz: [0.02709961, 0.030670166, 0.0289917]
        09:46:59.911 [main] DEBUG org.phomos.sampler.ColorTest - rbg2: [0.12155337, 0.1400473, 0.1430228]

Solution

  • I finally found the following Java class...

    https://imagej.nih.gov/ij/plugins/download/Color_Space_Converter.java

    The inner class ColorSpaceConverter has colorspace conversions that all appear to be mathematically reversible. I hacked away the outer class since it's part of some monolithic gui app, which I don't need.

    I learned a bit about the CIEXYZ and CIELAB colorspaces a long the way, but still nothing that explains why the standard JDK classes don't work like they should. Either way, the above code works!