Last active
July 24, 2019 01:12
-
-
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
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
/* | |
* 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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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)
tomakeLine(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