Hi all,
I check various posted and took a deep dive into “what is the best way to apply a threshold” from a python script, that allows me to
- either use the whole stack or the slice-by-slice histogram clacluation
- correct the threshold value for both ways
And at least it seems to work now (as far as I can tell). Any feedback or improvements are really appreciated. So far the part of the script doing the threshold is this
class ThresholdTools:
@staticmethod
def apply_autothreshold(hist, method='Otsu'):
if method == 'Otsu':
lowthresh = Auto_Threshold.Otsu(hist)
if method == 'Triangle':
lowthresh = Auto_Threshold.Triangle(hist)
if method == 'IJDefault':
lowthresh = Auto_Threshold.IJDefault(hist)
if method == 'Huang':
lowthresh = Auto_Threshold.Huang(hist)
if method == 'MaxEntropy':
lowthresh = Auto_Threshold.MaxEntropy(hist)
if method == 'Mean':
lowthresh = Auto_Threshold.Mean(hist)
if method == 'Shanbhag':
lowthresh = Auto_Threshold.Shanbhag(hist)
if method == 'Yen':
lowthresh = Auto_Threshold.Yen(hist)
if method == 'Li':
lowthresh = Auto_Threshold.Li(hist)
return lowthresh
@staticmethod
# helper function to appy threshold to whole stack
# using one corrected value for the stack
def apply_threshold_stack_corr(imp, lowth_corr, method='Otsu'):
# get the stacks
stack, nslices = ImageTools.getImageStack(imp)
for index in range(1, nslices + 1):
ip = stack.getProcessor(index)
# get the histogramm
hist = ip.getHistogram()
lowth = ThresholdTools.apply_autothreshold(hist, method=method)
ip.threshold(lowth_corr)
return imp
@staticmethod
# apply threshold either to whole stack or slice-by-slice
def apply_threshold(imp, method='Otsu',
background_threshold='dark',
stackopt=False,
corrf=1.0):
# one threshold value for the whole stack with correction
if stackopt:
# create argument string for the IJ.setAutoThreshold
thcmd = method + ' ' + background_threshold + ' stack'
# set threshold and get the lower threshold value
IJ.setAutoThreshold(imp, thcmd)
ip = imp.getProcessor()
hist = ip.getHistogram()
lowth = ip.getMinThreshold()
lowth_corr = int(round(lowth * corrf, 0))
# process stack with corrected threshold value
imp = ThresholdTools.apply_threshold_stack_corr(imp, lowth_corr,
method=method)
# threshold slice-by-slice with correction
if not stackopt:
# get the stack
stack, nslices = ImageTools.getImageStack(imp)
print('Thresholding slice-by-slice')
for index in range(1, nslices + 1):
ip = stack.getProcessor(index)
# get the histogramm
hist = ip.getHistogram()
# get the threshold value
lowth = ThresholdTools.apply_autothreshold(hist, method=method)
lowth_corr = int(round(lowth * corrf, 0))
ip.threshold(lowth_corr)
return imp
And I use it this way:
imp = ThresholdTools.apply_threshold(imp,
method=method,
background_threshold='dark',
stackopt=stackopt,
corrf=corrf)
imp.show()