Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: how to convert RGB color to CIE Lab

How can I present object Color in CIE Lab color model.

Color c = ...
float[] lab = {0,0,0};
...
c.getColorComponents(ColorSpace.getInstance(???), lab);

But I wasn't able to force this work with CIE Lab (despite of the fact that TYPE_Lab is presented in ColorSpace class)

Thx for attention.

like image 627
user562527 Avatar asked Jan 04 '11 12:01

user562527


People also ask

How do you convert RGB to Lab formula?

Description. lab = rgb2lab( RGB ) converts sRGB values to CIE 1976 L*a*b* values. lab = rgb2lab( RGB , Name,Value ) specifies additional conversion options, such as the color space of the RGB image, using one or more name-value pair arguments.

How do you convert RGB to color?

Hex to RGB conversionGet the 2 left digits of the hex color code and convert to decimal value to get the red color level. Get the 2 middle digits of the hex color code and convert to decimal value to get the green color level.

Why do we convert RGB to Lab?

First we have to convert image from RGB to LAB color space to reduce colors then algorithm can run faster.

How do you convert RGB to integer?

So far I use the following to get the RGB values from it: // rgbs is an array of integers, every single integer represents the // RGB values combined in some way int r = (int) ((Math. pow(256,3) + rgbs[k]) / 65536); int g = (int) (((Math. pow(256,3) + rgbs[k]) / 256 ) % 256 ); int b = (int) ((Math.


1 Answers

Here's my implementation:

import java.awt.color.ColorSpace;

public class CIELab extends ColorSpace {

    public static CIELab getInstance() {
        return Holder.INSTANCE;
    }

    @Override
    public float[] fromCIEXYZ(float[] colorvalue) {
        double l = f(colorvalue[1]);
        double L = 116.0 * l - 16.0;
        double a = 500.0 * (f(colorvalue[0]) - l);
        double b = 200.0 * (l - f(colorvalue[2]));
        return new float[] {(float) L, (float) a, (float) b};
    }

    @Override
    public float[] fromRGB(float[] rgbvalue) {
        float[] xyz = CIEXYZ.fromRGB(rgbvalue);
        return fromCIEXYZ(xyz);
    }

    @Override
    public float getMaxValue(int component) {
        return 128f;
    }

    @Override
    public float getMinValue(int component) {
        return (component == 0)? 0f: -128f;
    }    

    @Override
    public String getName(int idx) {
        return String.valueOf("Lab".charAt(idx));
    }

    @Override
    public float[] toCIEXYZ(float[] colorvalue) {
        double i = (colorvalue[0] + 16.0) * (1.0 / 116.0);
        double X = fInv(i + colorvalue[1] * (1.0 / 500.0));
        double Y = fInv(i);
        double Z = fInv(i - colorvalue[2] * (1.0 / 200.0));
        return new float[] {(float) X, (float) Y, (float) Z};
    }

    @Override
    public float[] toRGB(float[] colorvalue) {
        float[] xyz = toCIEXYZ(colorvalue);
        return CIEXYZ.toRGB(xyz);
    }

    CIELab() {
        super(ColorSpace.TYPE_Lab, 3);
    }

    private static double f(double x) {
        if (x > 216.0 / 24389.0) {
            return Math.cbrt(x);
        } else {
            return (841.0 / 108.0) * x + N;
        }
    }

    private static double fInv(double x) {
        if (x > 6.0 / 29.0) {
            return x*x*x;
        } else {
            return (108.0 / 841.0) * (x - N);
        }
    }

    private Object readResolve() {
        return getInstance();
    }

    private static class Holder {
        static final CIELab INSTANCE = new CIELab();
    }

    private static final long serialVersionUID = 5027741380892134289L;

    private static final ColorSpace CIEXYZ =
        ColorSpace.getInstance(ColorSpace.CS_CIEXYZ);

    private static final double N = 4.0 / 29.0;

}
like image 189
finnw Avatar answered Sep 16 '22 14:09

finnw