#@File[] (label = "Choose image files", required=false, style="files", persist="false", description="if no images are specified, \"Run on open images\" must be active") inputImages
#@Boolean (label = "Run on open images", value=false, description="Considers all open images. Make sure only images which should be adjusted are open") runOnOpen
#@Boolean (label = "Print used limits", value=false, description="prints the used contrast limits into the log window") printExtremes
#@Float (label = "Pixel saturation (%)", value="0.01", min="0.00", max="1.00", style="format:0.00", stepSize="0.01", description="Avoid too much oversaturation. Best stay below 0.10 %") saturation
#@Boolean (label = "Apply contrast (non-reversable)", value=false, description="If active the adjustment is a non-reversible point operation which kannot be undone") applyContrast
#@File (label = "Save in subfolder", required=false, style="directory", description="If empty, images will not be saved, otherwise end up as .tif images in the specified folder") resultsFolder
#@Boolean (label = "Run in background", value=false, description="Runs in background without showing the images.") runInBackground
#@String (label = "Usage", value="This tool applies the maximum possible contrast inside good scientific practice limits
equally to all considered images (all open ones or only the above specified).
Keep saturation values between 0.01-0.10. Higher values oversaturate too many pixels!
This is different from normal auto contrast since all images stay optically comparable.
All images which later should be optically compared need to be processed here together in one step!", visibility="MESSAGE") hint
var images;
if (runInBackground) {
setBatchMode(true);
}
if (!runOnOpen) {
imageString = "";
for (f = 0; f < inputImages.length; f++) {
open(inputImages[f]);
currentImage = getTitle();
if (bitDepth() == 24) {
close(currentImage);
} else {
imageString += getTitle() + ",";
}
}
images = split(imageString, ",");
if (images.length < 1) {
exit("No images to be adjusted");
}
images = Array.deleteIndex(images, images.length-1);
} else {
images = getList("image.titles");
}
channels = 0;
slices = 0;
frames = 0;
selectImage(images[0]);
inputDir = getDirectory("image");
for (i = 0; i < images.length; i++) {
selectImage(images[i]);
if (bitDepth() != 24) {
getDimensions(w, h, ch, sl, fr);
channels = Math.max(channels, ch);
slices = Math.max(slices, sl);
frames = Math.max(frames, fr);
}
}
min = newArray(channels);
max = newArray(channels);
absoluteMin = newArray(channels);
absoluteMax = newArray(channels);
Array.fill(absoluteMin, 1e30);
for (i = 0; i < images.length; i++) {
selectImage(images[i]);
if (bitDepth() != 24) {
getDimensions(width, height, currentChannel, currentSlice, currentFrames);
for (c = 0; c < currentChannel; c++) {
Stack.setChannel(c+1);
for (s = 0; s < currentSlice; s++) {
Stack.setSlice(s+1);
for (f = 0; f < currentFrames; f++) {
Stack.setFrame(f+1);
resetMinAndMax();
run("Enhance Contrast...", "saturated=" + saturation + " process_all use");
getMinAndMax(min[c], max[c]);
absoluteMin[c] = Math.min(absoluteMin[c], min[c]);
absoluteMax[c] = Math.max(absoluteMax[c], max[c]);
}
}
}
}
}
if (printExtremes) {
for (n = 0; n < channels; n++) {
print("Channel = " + (n+1) + " --> min = " + absoluteMin[n] + " / max = " + absoluteMax[n]);
}
}
for (i = 0; i < images.length; i++) {
selectImage(images[i]);
if (bitDepth() != 24) {
metadata = getMetadata("Info");
metadata = metadata + "\nContrast adjustment:\n";
getDimensions(width, height, currentChannel, currentSlice, currentFrames);
for (c = 0; c < currentChannel; c++) {
Stack.setChannel(c+1);
for (s = 0; s < currentSlice; s++) {
Stack.setSlice(s+1);
for (f = 0; f < currentFrames; f++) {
Stack.setFrame(f+1);
setMinAndMax(absoluteMin[c], absoluteMax[c]);
if (applyContrast) {
run("Apply LUT", "slice");
// resetMinAndMax();
}
metadata = metadata + "Channel " + c + ": min=" + absoluteMin[c] + " / max=" + absoluteMax[c] + "\n";
}
}
if (applyContrast) resetMinAndMax();
}
setMetadata("Info", metadata);
}
}
if (resultsFolder != 0) {
for (i = 0; i < images.length; i++) {
selectImage(images[i]);
if (bitDepth() != 24) {
save(resultsFolder + File.separator + File.getNameWithoutExtension(images[i]) + ".tif");
if (runInBackground) {
close(images[i]);
}
}
}
}
setBatchMode(false);