Last active
April 21, 2016 19:08
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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