Skip to content

Instantly share code, notes, and snippets.

@hageldave
Last active April 21, 2016 19:08
Show Gist options
  • Save hageldave/bbad70aea2cbd3242793b139569dcfbf to your computer and use it in GitHub Desktop.
Save hageldave/bbad70aea2cbd3242793b139569dcfbf to your computer and use it in GitHub Desktop.
convsion from RGB to CIE XYZ and further to CIE Lab and all the way back
public static void main(String[] args) throws MalformedURLException, IOException {
// String imgUrl = "http://sipi.usc.edu/database/preview/misc/4.1.07.png";
String imgUrl = "http://sipi.usc.edu/database/preview/misc/boat.512.png";
Img img = Img.createRemoteImg(ImageLoader.loadImage(new URL(imgUrl).openStream(),BufferedImage.TYPE_INT_ARGB));
System.out.println("start");
// to CIE XYZ colorspace (bound to [0..255] missing the factor 1/0.17697)
img.forEachParallel(px->{
px.setARGB( px.a(),
px.getGrey( 49, 31, 20),
px.getGrey(17697, 81240, 1063),
px.getGrey( 0, 1, 99));
});
// CIE XYZ to CIE LAB also bound to [0..255] with 128 being 0 chromaticity
final float labX = 255f;
final float labY = 255f;
final float labZ = 255f;
img.forEachParallel(px->{
float X = px.r();
float Y = px.g();
float Z = px.b();
float temp = labFunc(Y/labY);
int L = (int) (255*temp);
int a = (int) (127*(labFunc(X/labX)-temp)+128);
int b = (int) (127*(temp-labFunc(Z/labZ))+128);
px.setARGB(px.a(), L, a, b);
});
// do something with Lab
img.forEachParallel(px->{
float L = px.r();
float a = px.g()-128;
float b = px.b()-128;
float len = (float)Math.sqrt(a*a+b*b);
float angle =(float)Math.atan2(a, b);
len = 5;
angle = (float) ((L+280)*(Math.PI/180));
a = (float) (Math.sin(angle)*len);
b = (float) (Math.cos(angle)*len);
px.setValue(Pixel.argb_bounded(px.a(), (int)L, (int)a+128, (int)b+128));
});
// backtransform to XYZ
img.forEachParallel(px->{
float temp = px.r()/255.0f; // =L/255
int X = (int) (labX*labFuncInv(temp + (px.g()-128)/127.0f));
int Y = (int) (labY*labFuncInv(temp));
int Z = (int) (labZ*labFuncInv(temp - (px.b()-128)/127.0f));
px.setValue(Pixel.argb_bounded(px.a(), (int)X, (int)Y, (int)Z));
});
// CIE XYZ to RGB (for XYZ bound to [0..255] missing factor 1/0.17697)
img.forEachParallel(px->{
int r = px.getGrey(23646, -8966, -4680);
int g = px.getGrey(-5151, 14264, 887);
int b = px.getGrey( 52, -144, 10092);
px.setValue(Pixel.argb_bounded(px.a(),r, g, b));
});
System.out.println("done");
ImageSaver.saveImage(img.getRemoteBufferedImage(), "export.png");
}
static final float lab6_29 = 6.0f/29.0f;
static final float lab6_29_3 = lab6_29*lab6_29*lab6_29;
static final float lab1_3_29_6_2 = (1.0f/3.0f) * (29.0f/6.0f) * (29.0f/6.0f);
static float labFunc(float q){
return q > lab6_29_3 ? (float)Math.cbrt(q):lab1_3_29_6_2*q + (4.0f/29.0f);
}
static float labFuncInv(float q){
return q > lab6_29 ? q*q*q : 3*lab6_29*lab6_29*(q-(4.0f/29.0f));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment