Login  Register

Re: Custom thresholding a stack

Posted by Rasband, Wayne (NIH/NIMH) [E] on May 26, 2014; 12:22am
URL: http://imagej.273.s1.nabble.com/Custom-thresholding-a-stack-tp5007866p5007919.html

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