Skip to content

Instantly share code, notes, and snippets.

@lacan
Last active July 24, 2019 01:12
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save lacan/db89358ca5ba5d4308a52fc37cd05550 to your computer and use it in GitHub Desktop.
Reconvert color coded image to intensity based on color scale. #ImageJ #Fiji #Macro
/*
* Reconvert color LUT to intensity
* Olivier BURRI
* BioImaging and Optics Platform BIOP, EPFL
* In reply to an ImageJ Forum Post http://forum.imagej.net/t/split-colored-height-map-of-moon-in-greyscale-images/
* Provided As-Is
*/
// Before running this macro, make sure that you have an image called LUT with the color scalebar separately
// Keep original image reference
ori = getTitle();
// Build LUT
selectImage("LUT");
getDimensions(lw,lh,lc,lz,lt);
makeLine(lw/2,0,lw/2,lh);
getSelectionCoordinates(x,y);
lut = newArray(y[1]-y[0]+1);
k=0;
for(j=round(y[0]);j<round(y[1]);j++) {
lut[k] = getPixel(round(x[0]),j);
k++;
}
// Start converting the values
setBatchMode(true);
// Some information to create the new image
selectImage(ori);
getDimensions(w,h,c,z,t);
newImage(ori+" - Reconverted", "16-bit black", w, h, 1);
new = getTitle();
// Loop through all the pixels
for(i=0; i<w;i++) {
for(j=0; j<h;j++) {
selectImage(ori);
val = getPixel(i,j);
newVal = findValIdx(val, lut); // Where the magic happens
selectImage(new);
setPixel(i,j,newVal);
}
print("Done Row",i,"out of", w);
}
// clean up as much as possible without disturbing the values too much
run("Median...", "radius=0.1");
// Comment as needed, here the scalebar was inverted
run("Invert");
setBatchMode(false);
/*
* Magic function, returns the array index of the most similar LUT value
*/
function findValIdx(value, lut) {
valred = (val>>16)&0xff; // extract red byte (bits 23-17)
valgreen = (val>>8)&0xff; // extract green byte (bits 15-8)
valblue = val&0xff; // extract blue byte (bits 7-0)
minD = 99999999999;
for(i=0; i<lut.length; i++) {
lutred = (lut[i]>>16)&0xff; // extract red byte (bits 23-17)
lutgreen = (lut[i]>>8)&0xff; // extract green byte (bits 15-8)
lutblue = lut[i]&0xff; // extract blue byte (bits 7-0)
// Get euclidean distance
deltargb = sqrt((valred - lutred)*(valred - lutred) + (valgreen - lutgreen)*(valgreen - lutgreen) + (valblue - lutblue)*(valblue - lutblue));
// Keep minimum value
if(deltargb < minD) {
minD = deltargb;
minI = i;
// If 0 then we hav ethe exact match already
if(deltargb == 0) return minI;
}
}
return minI;
}
@fedebenelli
Copy link

fedebenelli commented Jul 24, 2019

Probably I misunderstood something in the description, but I'll like to add that I had to change the makeLine(lw/2,0,lw/2,lh) to makeLine(lw*9/10,0,lw*9/10,lh) in line 17, because that's were my scalebar was.
Thanks for the Macro! It really saved me from a lot of headaches

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment