diff --git a/src/main/resources/scripts/Plugins/NoiSee/NoiSee_Bead_Analysis.ijm b/src/main/resources/scripts/Plugins/NoiSee/NoiSee_Bead_Analysis.ijm index 702a0e236a44dc61a91ab1b9c30f6dc377be52a8..5a8cf10f49a01a6fe2f42f20ff1bad2e6a9c0bd0 100644 --- a/src/main/resources/scripts/Plugins/NoiSee/NoiSee_Bead_Analysis.ijm +++ b/src/main/resources/scripts/Plugins/NoiSee/NoiSee_Bead_Analysis.ijm @@ -476,6 +476,66 @@ function stripOmeSuffix(orig) { return orig; } +function detectValueRange() { + // detect the *actual* value range bit depth of a 16-bit image, i.e. if the + // image contains pixels in a range from 5 to 3978 the value range depth is + // 12 bits (possible values from 0 to 4095) + + // define the value range bit depths to test for (8 to 16): + possible_depths = Array.getSequence(17); + possible_depths = Array.slice(possible_depths, 8, 17); + + Stack.getStatistics(_, _, _, max, _, _); + logi("maximum pixel value in stack: " + max); + + saturated = false; + actual_depth = 16; + // traverse the possible depths array backwards: + for (i = lengthOf(possible_depths) - 1; i > 0; i--) { + sat = pow(2, possible_depths[i]) - 1; + logd("checking " + possible_depths[i] + " bit range (0-" + sat + ")"); + + if (max == sat) { + saturated = true; + actual_depth = possible_depths[i]; + logd("saturated " + actual_depth + "-bit image detected!"); + } else { + next_lower = pow(2, possible_depths[i-1]); + if (max < sat && max >= next_lower) { + actual_depth = possible_depths[i]; + logd("non-saturated " + actual_depth + "-bit image detected!"); + } + } + } + + msg_sat = "(not saturated)"; + if (saturated) + msg_sat = "(SATURATED!)"; + logd("\ndetected value range: " + actual_depth + " bit " + msg_sat); + + res = newArray(actual_depth, saturated); + return res; +} + +function mapTo8bitPreservingSaturation(effectiveBits) { + // convert an image with 12 or 16 bit effective value range depth to 8 bit + // preserving saturation in the sense that only saturated pixels (65535 for + // 16 bits and 4095 for 12 bits) are mapped to the 8 bit saturation value + // (255), avoiding the usual binning that would happen if simply the display + // range was adjusted to the min/max values of the image (resulting in + // over-saturation of wrongly mapped pixels) + if (effectiveBits == 16) { + run("Divide...", "value=257.50 stack"); + } else if (effectiveBits == 12) { + run("Divide...", "value=16.09 stack"); + } else { + print("Invalid VALUE range detected: " + effectiveBits); + print("Input image needs to have a value range of 8, 12 or 16 bits!"); + exit_show(); + } + run("8-bit"); +} + function clear_workspace() { /* * Ensure a clean workspace, i.e.