Custom thresholding a stack

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Custom thresholding a stack

Sidnei Paciornik
Dear All,

I have a stack of microtomography images which I need to segment to detect
some dark defects. As the average intensity and contrast of the slices
change along the stack, I cannot use a single threshold for all slices.

The natural solution would be to use an AutoThreshold option (let´s say
IJ_IsoData) and let it calculate a threshold for each slice. However, no
automatic method gives me a good threshold. I found out I can use
IJ_IsoData if I increase the upper threshold by a given factor.

So I wrote a macro that calls IJ_IsoData for each slice, gets the upper
threshold, multiplies this threshold by a factor, and then applies the new
upper threshold for each slice.

It seems OK until I try to convert each slice to binary. At this point the
program uses the upper threshold value of the LAST slice and applies it to
ALL other slices. Thus,  end up getting a fixed threshold for all slices,
which is what I wanted to avoid from the start.

What am I doing wrong?

Thank you!

Here is the simple macro code I use:
run("Duplicate...", "title=Binary duplicate");

mode = getString("Enter the background mode (bright/dark background)",
"bright");
if (mode == "bright") mode = "";
thmethod = "IJ_IsoData " + mode;

fator = getNumber("Enter the factor to increase the threshold", 1.15);

for (i=1; i<=nSlices; i++)
{
setSlice(i);
 setAutoThreshold(thmethod);
getThreshold(lower, upper);
if (mode =="dark")
 {
newlower = fator*lower;
setThreshold(newlower, upper);
 write(newlower, upper);
}
else
{
 newupper = fator*upper;
setThreshold(lower, newupper);
write(lower, newupper);
 }
}
run("Analyze Particles...", "show=Masks stack"); //I use this just to
create the binary mask
run("Invert LUT");
selectWindow("Binary");
close();

Prof. Sidnei Paciornik
Grupo de Análise de Imagens e Microscopia Digital
DEMa <http://www.dema.puc-rio.br/> - Departamento de Engenharia de Materiais
PUC-Rio <http://www.puc-rio.br/>
Rua Marquês de São Vicente 225
Prédio Leme, Sala 501L
Gávea - Rio de Janeiro - RJ
22451-900 - Brasil
tel: (55)(21)3527-1243

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Custom thresholding a stack

Michael Schmid
Hi Sidnei,

in ImageJ, the threshold is a property of the complete stack; you can't have different thresholds for different slices.
Thus, the last threshold that you set for the last slice overrides the previous threshold values that you have set when the previous slice was selected.

So, if you want different custom thresholds for different stack slices, you have to do the operation requiring the threshold (e.g. "Analyze Particles") separately for each slice.

Michael
________________________________________________________________

On May 22, 2014, at 21:49, Sidnei Paciornik wrote:

> Dear All,
>
> I have a stack of microtomography images which I need to segment to detect
> some dark defects. As the average intensity and contrast of the slices
> change along the stack, I cannot use a single threshold for all slices.
>
> The natural solution would be to use an AutoThreshold option (let´s say
> IJ_IsoData) and let it calculate a threshold for each slice. However, no
> automatic method gives me a good threshold. I found out I can use
> IJ_IsoData if I increase the upper threshold by a given factor.
>
> So I wrote a macro that calls IJ_IsoData for each slice, gets the upper
> threshold, multiplies this threshold by a factor, and then applies the new
> upper threshold for each slice.
>
> It seems OK until I try to convert each slice to binary. At this point the
> program uses the upper threshold value of the LAST slice and applies it to
> ALL other slices. Thus,  end up getting a fixed threshold for all slices,
> which is what I wanted to avoid from the start.
>
> What am I doing wrong?
>
> Thank you!
>
> Here is the simple macro code I use:
> run("Duplicate...", "title=Binary duplicate");
>
> mode = getString("Enter the background mode (bright/dark background)",
> "bright");
> if (mode == "bright") mode = "";
> thmethod = "IJ_IsoData " + mode;
>
> fator = getNumber("Enter the factor to increase the threshold", 1.15);
>
> for (i=1; i<=nSlices; i++)
> {
> setSlice(i);
> setAutoThreshold(thmethod);
> getThreshold(lower, upper);
> if (mode =="dark")
> {
> newlower = fator*lower;
> setThreshold(newlower, upper);
> write(newlower, upper);
> }
> else
> {
> newupper = fator*upper;
> setThreshold(lower, newupper);
> write(lower, newupper);
> }
> }
> run("Analyze Particles...", "show=Masks stack"); //I use this just to
> create the binary mask
> run("Invert LUT");
> selectWindow("Binary");
> close();

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Custom thresholding a stack

Rasband, Wayne (NIH/NIMH) [E]
In reply to this post by Sidnei Paciornik
On May 22, 2014, at 3:49 PM, Sidnei Paciornik wrote:

> Dear All,
>
> I have a stack of microtomography images which I need to segment to detect
> some dark defects. As the average intensity and contrast of the slices
> change along the stack, I cannot use a single threshold for all slices.
>
> The natural solution would be to use an AutoThreshold option (let´s say
> IJ_IsoData) and let it calculate a threshold for each slice. However, no
> automatic method gives me a good threshold. I found out I can use
> IJ_IsoData if I increase the upper threshold by a given factor.
>
> So I wrote a macro that calls IJ_IsoData for each slice, gets the upper
> threshold, multiplies this threshold by a factor, and then applies the new
> upper threshold for each slice.
>
> It seems OK until I try to convert each slice to binary. At this point the
> program uses the upper threshold value of the LAST slice and applies it to
> ALL other slices. Thus,  end up getting a fixed threshold for all slices,
> which is what I wanted to avoid from the start.
>
> What am I doing wrong?

Here is a version the macro that should work better. It requires the latest ImageJ daily build (1.49b11), which fixes a bug that caused the "n_situ" particle analyzer option to not work as expected when analyzing a single stack image. V1.49b11 also fixes a bug that caused the particle analyzer to hang if the threshold was set to 0-255.

  requires("1.49b");
  run("Duplicate...", "title=Binary duplicate");
  run("8-bit");
  Dialog.create("Custom Stack Threshold");
  Dialog.addChoice("Background:", newArray("dark","bright"));
  Dialog.addNumber("Factor to increase threshold:", 1.15);
  Dialog.show;
  mode = Dialog.getChoice;
  factor = Dialog.getNumber;
  if (mode=="bright") mode="";
  method = "IJ_IsoData " + mode;
  setOption("BlackBackground", true);
  for (i=1; i<=nSlices; i++) {
     setSlice(i);
     setAutoThreshold(method);
     getThreshold(lower, upper);
     if (mode =="dark")
        lower = lower/factor;
     else {
        upper = upper*factor;
        if (upper>255) upper=255;
     }
     setThreshold(lower, upper);
     run("Analyze Particles...", "show=Masks in_situ slice");
  }
  setSlice(1);
  resetThreshold;


> Thank you!
>
> Here is the simple macro code I use:
> run("Duplicate...", "title=Binary duplicate");
>
> mode = getString("Enter the background mode (bright/dark background)",
> "bright");
> if (mode == "bright") mode = "";
> thmethod = "IJ_IsoData " + mode;
>
> fator = getNumber("Enter the factor to increase the threshold", 1.15);
>
> for (i=1; i<=nSlices; i++)
> {
> setSlice(i);
> setAutoThreshold(thmethod);
> getThreshold(lower, upper);
> if (mode =="dark")
> {
> newlower = fator*lower;
> setThreshold(newlower, upper);
> write(newlower, upper);
> }
> else
> {
> newupper = fator*upper;
> setThreshold(lower, newupper);
> write(lower, newupper);
> }
> }
> run("Analyze Particles...", "show=Masks stack"); //I use this just to
> create the binary mask
> run("Invert LUT");
> selectWindow("Binary");
> close();
>
> Prof. Sidnei Paciornik
> Grupo de Análise de Imagens e Microscopia Digital
> DEMa <http://www.dema.puc-rio.br/> - Departamento de Engenharia de Materiais
> PUC-Rio <http://www.puc-rio.br/>
> Rua Marquês de São Vicente 225
> Prédio Leme, Sala 501L
> Gávea - Rio de Janeiro - RJ
> 22451-900 - Brasil
> tel: (55)(21)3527-1243

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html