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