Count cells in stack?

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

Count cells in stack?

Mike Myerburg
Hi-

I study polarized cells that form a pseudostratified epithelial layer on
filters.  I am trying to make a plugin that will count the # of nuclei
present in a stack.  Because the cells are not a monolayer, I cannot
accurately count them by making an zprojection and then do standard
automated counting (the nuclei are occasionally on top of each other).
It seems that it "should" be possible to make a plugin to analyze the
nuclei in 3D and then count the number within a stack.

Has something like this already been made?  Any suggestions?

Cheers, Mike
Reply | Threaded
Open this post in threaded view
|

Re: Count cells in stack?

simon andrews (BI)
On 11 Apr 2008, at 19:54, Mike Myerburg wrote:

> Hi-
>
> I study polarized cells that form a pseudostratified epithelial  
> layer on filters.  I am trying to make a plugin that will count the  
> # of nuclei present in a stack.  Because the cells are not a  
> monolayer, I cannot accurately count them by making an zprojection  
> and then do standard automated counting (the nuclei are  
> occasionally on top of each other). It seems that it "should" be  
> possible to make a plugin to analyze the nuclei in 3D and then  
> count the number within a stack.

I've got a plugin which detects objects in 3D which might work for  
this purpose.  It's designed to measure 3D distances between objects,  
but should be able to be used to simply count objects if that's all  
you wanted to do.  It doesn't have any special facility for  
identifying nuclei but just builds features out of groups of voxels  
which are sufficiently bright.

It's not quite yet at a stage where I'm ready to make a public  
release, but if you want to try it send me a mail off list and I'll  
send you a copy.  If you want to you can send me an example image  
stack and I can run the plugin on it here to see if I can get it to  
do what you want.

TTFN

Simon.
Reply | Threaded
Open this post in threaded view
|

Re: Count cells in stack?

Fernando Sales
In reply to this post by Mike Myerburg
Mike,

if you have a program that segments and identify the cells in each slice of
the stack, you can generate a binary mask and count the number of "islands"
of white pixels (suppose that the cells are white and the backgroung is
black). I've developed a plugin which implements a labelling algorithm to
identify different objects in a binary scene. Then, this way you can count
the number of cells slice by slice.

Cheers,
Fernando
On Fri, Apr 11, 2008 at 3:54 PM, Mike Myerburg <[hidden email]> wrote:

> Hi-
>
> I study polarized cells that form a pseudostratified epithelial layer on
> filters.  I am trying to make a plugin that will count the # of nuclei
> present in a stack.  Because the cells are not a monolayer, I cannot
> accurately count them by making an zprojection and then do standard
> automated counting (the nuclei are occasionally on top of each other). It
> seems that it "should" be possible to make a plugin to analyze the nuclei in
> 3D and then count the number within a stack.
>
> Has something like this already been made?  Any suggestions?
>
> Cheers, Mike
>



--
**************************************************
Fernando José Ribeiro Sales
**************************************************
Email: [hidden email]
Tel: (11) 82020303
**************************************************
Reply | Threaded
Open this post in threaded view
|

Re: Count cells in stack?

vbindokas
Dear all,
    The 3-D objects counter plugin does a good job for isolated objects
(defined by  threshold), but lacks a 3D watershed routine. The existing
watershed routines either don't work well in 3D or take too long.  
Uneven heterochromatin staining poses another difficulty. I wrote this
macro to separate most nuclei based on XY and resampled XZ 2D
watershedding, plus refinement of identities by Euclidean distances.
It's not perfect, but seems to do a good job with a few sample data sets
I collected. It doesn't overcount as far as tested. It background
corrects and outputs a labeled RGB map (plus the text stats from 3D
objects counter plugin). Default values work for 20-30 pixel-diameter
nuclei sampled is 1-2 um Zstacks. Yu may need to tune rolling ball
diameter, smoothing, thresholds, etc. (it's a brute-force approach, so
I'd be interested in improvements/comments)
    I include the text here (watch for broken code lines), or you can
download it from our macro site (sample data should be posted today).  
http://digital.bsd.uchicago.edu/imagejmacros.html
_________cut below for 3D_nuclei_counter.txt _____________________

//macro to count DAPI nuclei in confocal Z stack (16bit)
//it reduces the image to the object centers then counts those by means
of the
// 3D_object_counter plugin (required), and that takes care of merging
overlapped objects
// http://rsb.info.nih.gov/ij/plugins/track/objects.html
// Final output is a numbered red-green stack plus the report
// tuning steps would be the median radii and the expand diameters (decr
both for low magnification)
//   Vytas Bindokas, Univ of Chicago, Apr 2008
//    this uses distance maps plus XY and XZ watershed steps to split
objects "3D"; action is not perfect !
//  tuning steps are the rolling ball diam, the remove outlier diams;
use smaller for low magnification input

run("Colors...", "foreground=white background=black selection=yellow");
t1=getTitle();
run("Set Measurements...", "  mean centroid redirect=None decimal=6");
n0=nSlices;
h=getHeight();
w=getWidth();
getVoxelSize(width, height, depth, unit);
wi=width;
hei=height;
d=depth;
u=unit;
run("Subtract Background...", "rolling=25 stack");    //try diameter of
nucleus
run("Duplicate...", "title=countme duplicate");
run("Set Scale...", "distance=0 known=1 pixel=1 unit=pixel");
setSlice(n0/2);
run("Enhance Contrast", "saturated=0.1 normalize normalize_all ");    
//correct for Z intensity loss
run("Remove Outliers...", "radius=7 threshold=0 which=Bright stack");    
//this smooths DAPI heterochromatin staining patterns
run("Remove Outliers...", "radius=2 threshold=0 which=Dark stack");    
    //smooths background

    // tuning point below

setAutoThreshold();            //you can set a fixed range, if needed,
by activating next line...
//setThreshold(9500, 65535);        //goal is to pick up entire nucleus
(vs uneven bits)
run("Make Binary", " ");      
run("Median...", "radius=3 stack");     //to smooth and fill some holes
run("Watershed", "stack");
run("Distance Map", "stack");        // "find" centers for next steps
(seems to aid splitting XY and XZ)
run("Grays");

mo=1;                //this is noise tolerance, lower = finds more
maxima (tune as needed); values are DISTANCE TO EDGE
for (i=1; i<=nSlices; i++){
 setSlice(i);      
 getStatistics(area, mean, min, max);      
 if (max>min){                    //skip if frame blank...
 run("Find Maxima...", "noise="+mo+" output=[Point Selection]");
 run("Enlarge...", "enlarge=4");                    //pad around each
maximum; tune if need be
 run("Clear Outside", "slice");
 }
 run("Select None");
}

makeLine(0, 0, w, 0);
run("Reslice [/]...", "input=1 output=1 slice="+h+"");        //repeat
watershedding and localization in Z axis
rename("xz");
run("Enhance Contrast", "saturated=0.1");
run("Median...", "radius=1 stack");
    run("Convert to Mask", "  black");
    run("Watershed", "stack");
    run("Distance Map", "stack");

for (i=1; i<=nSlices; i++){
 setSlice(i);
getStatistics(area, mean, min, max);
if (max>min){      
 run("Find Maxima...", "noise=0 output=[Point Selection]");    //since
this is pixels, not true Z, I suggest keeping these values LOW
 run("Enlarge...", "enlarge=1");
 //run("Fill", "slice");
 }
 run("Select None");
}
n1=nSlices;
h1=getHeight();
w1=getWidth();
makeLine(0, 0, w1, 0);
//    run("Set Scale...", "distance=0 known=1 pixel=1 unit=pixel");
run("Reslice [/]...", "input="+1+" output="+1+" slice="+h1);            
//return to XY view
rename("zvu");
setVoxelSize(wi, hei, d, u);
setSlice(nSlices/2);
run("Grays");
run("Despeckle", "stack");

    //  3D counts can take much memory!  consider going 8-bit here if it
can't run in OS limits
        //the min & max size below can select what to 3D count
run(" 3D objects counter", "threshold=1 slice=25 min=6 max=13107200
particles dot=3 numbers font=12");

run("8-bit");                //the next few lines build the red map data
for overlays
setMinAndMax(0, 1);
run("Apply LUT", "stack");
selectWindow("xz");
close();
selectWindow("countme");
close();
selectWindow("zvu");
close();
selectWindow(t1);
run("Enhance Contrast", "saturated=0.5 normalize normalize_all");
run("Despeckle", "stack");
run("RGB Merge...", "red=[Particles zvu] green=["+t1+"] blue=*None*
gray=*None*");
rename("counted"+t1);

______________ end cut ___________________________



Fernando Sales wrote:

> Mike,
>
> if you have a program that segments and identify the cells in each slice of
> the stack, you can generate a binary mask and count the number of "islands"
> of white pixels (suppose that the cells are white and the backgroung is
> black). I've developed a plugin which implements a labelling algorithm to
> identify different objects in a binary scene. Then, this way you can count
> the number of cells slice by slice.
>
> Cheers,
> Fernando
> On Fri, Apr 11, 2008 at 3:54 PM, Mike Myerburg <[hidden email]> wrote:
>
>  
>> Hi-
>>
>> I study polarized cells that form a pseudostratified epithelial layer on
>> filters.  I am trying to make a plugin that will count the # of nuclei
>> present in a stack.  Because the cells are not a monolayer, I cannot
>> accurately count them by making an zprojection and then do standard
>> automated counting (the nuclei are occasionally on top of each other). It
>> seems that it "should" be possible to make a plugin to analyze the nuclei in
>> 3D and then count the number within a stack.
>>
>> Has something like this already been made?  Any suggestions?
>>
>> Cheers, Mike
>>
>>    
>
>
>
>  

--
__

Vytas Bindokas, Ph.D.
Research Assoc. / Assoc. Prof.,
Director, BSD Light Microscopy Core Facility
Dept Neurobiol Pharmacol Physiol MC0926
947 E 58th Street
The University of Chicago
Chicago IL 60637
Room Abbott 120
773-702-4875

email [hidden email]
web site for LMCF:
http://digital.bsd.uchicago.edu/index.html



This email is intended only for the use of the individual or entity to which it is addressed and may contain information that is privileged and confidential.  If the reader of this email message is not the intended recipient, you are hereby notified that any dissemination, distribution, or copying of this communication is prohibited.  If you have received this email in error, please notify the sender and destroy/delete all copies of the transmittal.  Thank you.
Reply | Threaded
Open this post in threaded view
|

Re: Count cells in stack?

Mike Myerburg
Thanks-

This looks to be what I am looking for.  I have been trying a similiar
approach, but have stumbled up on the 3D watershedding.  I will give
this a try and let you know of any changes that work well for me.

Cheers, Mike

vbindoka wrote:

> Dear all,
>    The 3-D objects counter plugin does a good job for isolated objects
> (defined by  threshold), but lacks a 3D watershed routine. The existing
> watershed routines either don't work well in 3D or take too long.  
> Uneven heterochromatin staining poses another difficulty. I wrote this
> macro to separate most nuclei based on XY and resampled XZ 2D
> watershedding, plus refinement of identities by Euclidean distances.
> It's not perfect, but seems to do a good job with a few sample data sets
> I collected. It doesn't overcount as far as tested. It background
> corrects and outputs a labeled RGB map (plus the text stats from 3D
> objects counter plugin). Default values work for 20-30 pixel-diameter
> nuclei sampled is 1-2 um Zstacks. Yu may need to tune rolling ball
> diameter, smoothing, thresholds, etc. (it's a brute-force approach, so
> I'd be interested in improvements/comments)
>    I include the text here (watch for broken code lines), or you can
> download it from our macro site (sample data should be posted today).  
> http://digital.bsd.uchicago.edu/imagejmacros.html
> _________cut below for 3D_nuclei_counter.txt _____________________
>
> //macro to count DAPI nuclei in confocal Z stack (16bit)
> //it reduces the image to the object centers then counts those by means
> of the
> // 3D_object_counter plugin (required), and that takes care of merging
> overlapped objects
> // http://rsb.info.nih.gov/ij/plugins/track/objects.html
> // Final output is a numbered red-green stack plus the report
> // tuning steps would be the median radii and the expand diameters (decr
> both for low magnification)
> //   Vytas Bindokas, Univ of Chicago, Apr 2008
> //    this uses distance maps plus XY and XZ watershed steps to split
> objects "3D"; action is not perfect !
> //  tuning steps are the rolling ball diam, the remove outlier diams;
> use smaller for low magnification input
>
> run("Colors...", "foreground=white background=black selection=yellow");
> t1=getTitle();
> run("Set Measurements...", "  mean centroid redirect=None decimal=6");
> n0=nSlices;
> h=getHeight();
> w=getWidth();
> getVoxelSize(width, height, depth, unit);
> wi=width;
> hei=height;
> d=depth;
> u=unit;
> run("Subtract Background...", "rolling=25 stack");    //try diameter of
> nucleus
> run("Duplicate...", "title=countme duplicate");
> run("Set Scale...", "distance=0 known=1 pixel=1 unit=pixel");
> setSlice(n0/2);
> run("Enhance Contrast", "saturated=0.1 normalize normalize_all ");    
> //correct for Z intensity loss
> run("Remove Outliers...", "radius=7 threshold=0 which=Bright stack");    
> //this smooths DAPI heterochromatin staining patterns
> run("Remove Outliers...", "radius=2 threshold=0 which=Dark stack");    
>    //smooths background
>
>    // tuning point below
>
> setAutoThreshold();            //you can set a fixed range, if needed,
> by activating next line...
> //setThreshold(9500, 65535);        //goal is to pick up entire nucleus
> (vs uneven bits)
> run("Make Binary", " ");       run("Median...", "radius=3 stack");    
> //to smooth and fill some holes
> run("Watershed", "stack");
> run("Distance Map", "stack");        // "find" centers for next steps
> (seems to aid splitting XY and XZ)
> run("Grays");
>
> mo=1;                //this is noise tolerance, lower = finds more
> maxima (tune as needed); values are DISTANCE TO EDGE
> for (i=1; i<=nSlices; i++){
> setSlice(i);       getStatistics(area, mean, min, max);       if
> (max>min){                    //skip if frame blank...
> run("Find Maxima...", "noise="+mo+" output=[Point Selection]");
> run("Enlarge...", "enlarge=4");                    //pad around each
> maximum; tune if need be
> run("Clear Outside", "slice");
> }
> run("Select None");
> }
>
> makeLine(0, 0, w, 0);
> run("Reslice [/]...", "input=1 output=1 slice="+h+"");        //repeat
> watershedding and localization in Z axis
> rename("xz");
> run("Enhance Contrast", "saturated=0.1");
> run("Median...", "radius=1 stack");
>    run("Convert to Mask", "  black");
>    run("Watershed", "stack");
>    run("Distance Map", "stack");
>
> for (i=1; i<=nSlices; i++){
> setSlice(i);
> getStatistics(area, mean, min, max);
> if (max>min){       run("Find Maxima...", "noise=0 output=[Point
> Selection]");    //since this is pixels, not true Z, I suggest keeping
> these values LOW
> run("Enlarge...", "enlarge=1");
> //run("Fill", "slice");
> }
> run("Select None");
> }
> n1=nSlices;
> h1=getHeight();
> w1=getWidth();
> makeLine(0, 0, w1, 0);
> //    run("Set Scale...", "distance=0 known=1 pixel=1 unit=pixel");
> run("Reslice [/]...", "input="+1+" output="+1+" slice="+h1);            
> //return to XY view
> rename("zvu");
> setVoxelSize(wi, hei, d, u);
> setSlice(nSlices/2);
> run("Grays");
> run("Despeckle", "stack");
>
>    //  3D counts can take much memory!  consider going 8-bit here if it
> can't run in OS limits
>        //the min & max size below can select what to 3D count
> run(" 3D objects counter", "threshold=1 slice=25 min=6 max=13107200
> particles dot=3 numbers font=12");
>
> run("8-bit");                //the next few lines build the red map data
> for overlays
> setMinAndMax(0, 1);
> run("Apply LUT", "stack");
> selectWindow("xz");
> close();
> selectWindow("countme");
> close();
> selectWindow("zvu");
> close();
> selectWindow(t1);
> run("Enhance Contrast", "saturated=0.5 normalize normalize_all");
> run("Despeckle", "stack");
> run("RGB Merge...", "red=[Particles zvu] green=["+t1+"] blue=*None*
> gray=*None*");
> rename("counted"+t1);
>
> ______________ end cut ___________________________
>
>
>
> Fernando Sales wrote:
>> Mike,
>>
>> if you have a program that segments and identify the cells in each
>> slice of
>> the stack, you can generate a binary mask and count the number of
>> "islands"
>> of white pixels (suppose that the cells are white and the backgroung is
>> black). I've developed a plugin which implements a labelling algorithm to
>> identify different objects in a binary scene. Then, this way you can
>> count
>> the number of cells slice by slice.
>>
>> Cheers,
>> Fernando
>> On Fri, Apr 11, 2008 at 3:54 PM, Mike Myerburg
>> <[hidden email]> wrote:
>>
>>  
>>> Hi-
>>>
>>> I study polarized cells that form a pseudostratified epithelial layer on
>>> filters.  I am trying to make a plugin that will count the # of nuclei
>>> present in a stack.  Because the cells are not a monolayer, I cannot
>>> accurately count them by making an zprojection and then do standard
>>> automated counting (the nuclei are occasionally on top of each
>>> other). It
>>> seems that it "should" be possible to make a plugin to analyze the
>>> nuclei in
>>> 3D and then count the number within a stack.
>>>
>>> Has something like this already been made?  Any suggestions?
>>>
>>> Cheers, Mike
>>>
>>>    
>>
>>
>>
>>  
Reply | Threaded
Open this post in threaded view
|

Re: Count cells in stack?

Mike Myerburg
In reply to this post by vbindokas
This plugin is working very well for me.  Thanks so much for your work
and sharing.  I still need to tweak it a bit as it misses a few in
stacks with tightly packed cells.  But it is quite close.

Thanks for the help, Mike

vbindoka wrote:

> Dear all,
>    The 3-D objects counter plugin does a good job for isolated objects
> (defined by  threshold), but lacks a 3D watershed routine. The existing
> watershed routines either don't work well in 3D or take too long.  
> Uneven heterochromatin staining poses another difficulty. I wrote this
> macro to separate most nuclei based on XY and resampled XZ 2D
> watershedding, plus refinement of identities by Euclidean distances.
> It's not perfect, but seems to do a good job with a few sample data sets
> I collected. It doesn't overcount as far as tested. It background
> corrects and outputs a labeled RGB map (plus the text stats from 3D
> objects counter plugin). Default values work for 20-30 pixel-diameter
> nuclei sampled is 1-2 um Zstacks. Yu may need to tune rolling ball
> diameter, smoothing, thresholds, etc. (it's a brute-force approach, so
> I'd be interested in improvements/comments)
>    I include the text here (watch for broken code lines), or you can
> download it from our macro site (sample data should be posted today).  
> http://digital.bsd.uchicago.edu/imagejmacros.html
> _________cut below for 3D_nuclei_counter.txt _____________________
>
> //macro to count DAPI nuclei in confocal Z stack (16bit)
> //it reduces the image to the object centers then counts those by means
> of the
> // 3D_object_counter plugin (required), and that takes care of merging
> overlapped objects
> // http://rsb.info.nih.gov/ij/plugins/track/objects.html
> // Final output is a numbered red-green stack plus the report
> // tuning steps would be the median radii and the expand diameters (decr
> both for low magnification)
> //   Vytas Bindokas, Univ of Chicago, Apr 2008
> //    this uses distance maps plus XY and XZ watershed steps to split
> objects "3D"; action is not perfect !
> //  tuning steps are the rolling ball diam, the remove outlier diams;
> use smaller for low magnification input
>
> run("Colors...", "foreground=white background=black selection=yellow");
> t1=getTitle();
> run("Set Measurements...", "  mean centroid redirect=None decimal=6");
> n0=nSlices;
> h=getHeight();
> w=getWidth();
> getVoxelSize(width, height, depth, unit);
> wi=width;
> hei=height;
> d=depth;
> u=unit;
> run("Subtract Background...", "rolling=25 stack");    //try diameter of
> nucleus
> run("Duplicate...", "title=countme duplicate");
> run("Set Scale...", "distance=0 known=1 pixel=1 unit=pixel");
> setSlice(n0/2);
> run("Enhance Contrast", "saturated=0.1 normalize normalize_all ");    
> //correct for Z intensity loss
> run("Remove Outliers...", "radius=7 threshold=0 which=Bright stack");    
> //this smooths DAPI heterochromatin staining patterns
> run("Remove Outliers...", "radius=2 threshold=0 which=Dark stack");    
>    //smooths background
>
>    // tuning point below
>
> setAutoThreshold();            //you can set a fixed range, if needed,
> by activating next line...
> //setThreshold(9500, 65535);        //goal is to pick up entire nucleus
> (vs uneven bits)
> run("Make Binary", " ");       run("Median...", "radius=3 stack");    
> //to smooth and fill some holes
> run("Watershed", "stack");
> run("Distance Map", "stack");        // "find" centers for next steps
> (seems to aid splitting XY and XZ)
> run("Grays");
>
> mo=1;                //this is noise tolerance, lower = finds more
> maxima (tune as needed); values are DISTANCE TO EDGE
> for (i=1; i<=nSlices; i++){
> setSlice(i);       getStatistics(area, mean, min, max);       if
> (max>min){                    //skip if frame blank...
> run("Find Maxima...", "noise="+mo+" output=[Point Selection]");
> run("Enlarge...", "enlarge=4");                    //pad around each
> maximum; tune if need be
> run("Clear Outside", "slice");
> }
> run("Select None");
> }
>
> makeLine(0, 0, w, 0);
> run("Reslice [/]...", "input=1 output=1 slice="+h+"");        //repeat
> watershedding and localization in Z axis
> rename("xz");
> run("Enhance Contrast", "saturated=0.1");
> run("Median...", "radius=1 stack");
>    run("Convert to Mask", "  black");
>    run("Watershed", "stack");
>    run("Distance Map", "stack");
>
> for (i=1; i<=nSlices; i++){
> setSlice(i);
> getStatistics(area, mean, min, max);
> if (max>min){       run("Find Maxima...", "noise=0 output=[Point
> Selection]");    //since this is pixels, not true Z, I suggest keeping
> these values LOW
> run("Enlarge...", "enlarge=1");
> //run("Fill", "slice");
> }
> run("Select None");
> }
> n1=nSlices;
> h1=getHeight();
> w1=getWidth();
> makeLine(0, 0, w1, 0);
> //    run("Set Scale...", "distance=0 known=1 pixel=1 unit=pixel");
> run("Reslice [/]...", "input="+1+" output="+1+" slice="+h1);            
> //return to XY view
> rename("zvu");
> setVoxelSize(wi, hei, d, u);
> setSlice(nSlices/2);
> run("Grays");
> run("Despeckle", "stack");
>
>    //  3D counts can take much memory!  consider going 8-bit here if it
> can't run in OS limits
>        //the min & max size below can select what to 3D count
> run(" 3D objects counter", "threshold=1 slice=25 min=6 max=13107200
> particles dot=3 numbers font=12");
>
> run("8-bit");                //the next few lines build the red map data
> for overlays
> setMinAndMax(0, 1);
> run("Apply LUT", "stack");
> selectWindow("xz");
> close();
> selectWindow("countme");
> close();
> selectWindow("zvu");
> close();
> selectWindow(t1);
> run("Enhance Contrast", "saturated=0.5 normalize normalize_all");
> run("Despeckle", "stack");
> run("RGB Merge...", "red=[Particles zvu] green=["+t1+"] blue=*None*
> gray=*None*");
> rename("counted"+t1);
>
> ______________ end cut ___________________________
>
>
>
> Fernando Sales wrote:
>> Mike,
>>
>> if you have a program that segments and identify the cells in each
>> slice of
>> the stack, you can generate a binary mask and count the number of
>> "islands"
>> of white pixels (suppose that the cells are white and the backgroung is
>> black). I've developed a plugin which implements a labelling algorithm to
>> identify different objects in a binary scene. Then, this way you can
>> count
>> the number of cells slice by slice.
>>
>> Cheers,
>> Fernando
>> On Fri, Apr 11, 2008 at 3:54 PM, Mike Myerburg
>> <[hidden email]> wrote:
>>
>>  
>>> Hi-
>>>
>>> I study polarized cells that form a pseudostratified epithelial layer on
>>> filters.  I am trying to make a plugin that will count the # of nuclei
>>> present in a stack.  Because the cells are not a monolayer, I cannot
>>> accurately count them by making an zprojection and then do standard
>>> automated counting (the nuclei are occasionally on top of each
>>> other). It
>>> seems that it "should" be possible to make a plugin to analyze the
>>> nuclei in
>>> 3D and then count the number within a stack.
>>>
>>> Has something like this already been made?  Any suggestions?
>>>
>>> Cheers, Mike
>>>
>>>    
>>
>>
>>
>>  
>
Reply | Threaded
Open this post in threaded view
|

Re: Count cells in stack?

Dorota
Hi!

I am working with a similar problem as you (counting DAPI stained nuclei in a Z-stack... in my case, it is germ cells in the C.elegans gonad).

The plugin "count 3D nuclei" is great, but I find that it misses a few when cells are tightly packed (for me, this is most of the time).

In order to work around this, I am using the stack generated with the "count 3D nuclei plugin" (green cells w/ red numbered dots) and then manually adding the couple cells it missed using the "Cell Counter" plugin.

However, I find that it would be helpful if there was an option to have the numbers propagated through all the stacks (similar to the "Show All" option on "Cell Counter"). Have you by chance figured out how to do this? Also, it would be nice to have the option to hide the numbers (so that I have only red dots propaged throughout the stacks, without the numbers). Do you know how to do this? I am not a pro with Java!

Thanks so much!!!

Dorota

Mike Myerburg wrote
This plugin is working very well for me.  Thanks so much for your work
and sharing.  I still need to tweak it a bit as it misses a few in
stacks with tightly packed cells.  But it is quite close.

Thanks for the help, Mike

vbindoka wrote:
> Dear all,
>    The 3-D objects counter plugin does a good job for isolated objects
> (defined by  threshold), but lacks a 3D watershed routine. The existing
> watershed routines either don't work well in 3D or take too long.  
> Uneven heterochromatin staining poses another difficulty. I wrote this
> macro to separate most nuclei based on XY and resampled XZ 2D
> watershedding, plus refinement of identities by Euclidean distances.
> It's not perfect, but seems to do a good job with a few sample data sets
> I collected. It doesn't overcount as far as tested. It background
> corrects and outputs a labeled RGB map (plus the text stats from 3D
> objects counter plugin). Default values work for 20-30 pixel-diameter
> nuclei sampled is 1-2 um Zstacks. Yu may need to tune rolling ball
> diameter, smoothing, thresholds, etc. (it's a brute-force approach, so
> I'd be interested in improvements/comments)
>    I include the text here (watch for broken code lines), or you can
> download it from our macro site (sample data should be posted today).  
> http://digital.bsd.uchicago.edu/imagejmacros.html
> _________cut below for 3D_nuclei_counter.txt _____________________
>
> //macro to count DAPI nuclei in confocal Z stack (16bit)
> //it reduces the image to the object centers then counts those by means
> of the
> // 3D_object_counter plugin (required), and that takes care of merging
> overlapped objects
> // http://rsb.info.nih.gov/ij/plugins/track/objects.html
> // Final output is a numbered red-green stack plus the report
> // tuning steps would be the median radii and the expand diameters (decr
> both for low magnification)
> //   Vytas Bindokas, Univ of Chicago, Apr 2008
> //    this uses distance maps plus XY and XZ watershed steps to split
> objects "3D"; action is not perfect !
> //  tuning steps are the rolling ball diam, the remove outlier diams;
> use smaller for low magnification input
>
> run("Colors...", "foreground=white background=black selection=yellow");
> t1=getTitle();
> run("Set Measurements...", "  mean centroid redirect=None decimal=6");
> n0=nSlices;
> h=getHeight();
> w=getWidth();
> getVoxelSize(width, height, depth, unit);
> wi=width;
> hei=height;
> d=depth;
> u=unit;
> run("Subtract Background...", "rolling=25 stack");    //try diameter of
> nucleus
> run("Duplicate...", "title=countme duplicate");
> run("Set Scale...", "distance=0 known=1 pixel=1 unit=pixel");
> setSlice(n0/2);
> run("Enhance Contrast", "saturated=0.1 normalize normalize_all ");    
> //correct for Z intensity loss
> run("Remove Outliers...", "radius=7 threshold=0 which=Bright stack");    
> //this smooths DAPI heterochromatin staining patterns
> run("Remove Outliers...", "radius=2 threshold=0 which=Dark stack");    
>    //smooths background
>
>    // tuning point below
>
> setAutoThreshold();            //you can set a fixed range, if needed,
> by activating next line...
> //setThreshold(9500, 65535);        //goal is to pick up entire nucleus
> (vs uneven bits)
> run("Make Binary", " ");       run("Median...", "radius=3 stack");    
> //to smooth and fill some holes
> run("Watershed", "stack");
> run("Distance Map", "stack");        // "find" centers for next steps
> (seems to aid splitting XY and XZ)
> run("Grays");
>
> mo=1;                //this is noise tolerance, lower = finds more
> maxima (tune as needed); values are DISTANCE TO EDGE
> for (i=1; i<=nSlices; i++){
> setSlice(i);       getStatistics(area, mean, min, max);       if
> (max>min){                    //skip if frame blank...
> run("Find Maxima...", "noise="+mo+" output=[Point Selection]");
> run("Enlarge...", "enlarge=4");                    //pad around each
> maximum; tune if need be
> run("Clear Outside", "slice");
> }
> run("Select None");
> }
>
> makeLine(0, 0, w, 0);
> run("Reslice [/]...", "input=1 output=1 slice="+h+"");        //repeat
> watershedding and localization in Z axis
> rename("xz");
> run("Enhance Contrast", "saturated=0.1");
> run("Median...", "radius=1 stack");
>    run("Convert to Mask", "  black");
>    run("Watershed", "stack");
>    run("Distance Map", "stack");
>
> for (i=1; i<=nSlices; i++){
> setSlice(i);
> getStatistics(area, mean, min, max);
> if (max>min){       run("Find Maxima...", "noise=0 output=[Point
> Selection]");    //since this is pixels, not true Z, I suggest keeping
> these values LOW
> run("Enlarge...", "enlarge=1");
> //run("Fill", "slice");
> }
> run("Select None");
> }
> n1=nSlices;
> h1=getHeight();
> w1=getWidth();
> makeLine(0, 0, w1, 0);
> //    run("Set Scale...", "distance=0 known=1 pixel=1 unit=pixel");
> run("Reslice [/]...", "input="+1+" output="+1+" slice="+h1);            
> //return to XY view
> rename("zvu");
> setVoxelSize(wi, hei, d, u);
> setSlice(nSlices/2);
> run("Grays");
> run("Despeckle", "stack");
>
>    //  3D counts can take much memory!  consider going 8-bit here if it
> can't run in OS limits
>        //the min & max size below can select what to 3D count
> run(" 3D objects counter", "threshold=1 slice=25 min=6 max=13107200
> particles dot=3 numbers font=12");
>
> run("8-bit");                //the next few lines build the red map data
> for overlays
> setMinAndMax(0, 1);
> run("Apply LUT", "stack");
> selectWindow("xz");
> close();
> selectWindow("countme");
> close();
> selectWindow("zvu");
> close();
> selectWindow(t1);
> run("Enhance Contrast", "saturated=0.5 normalize normalize_all");
> run("Despeckle", "stack");
> run("RGB Merge...", "red=[Particles zvu] green=["+t1+"] blue=*None*
> gray=*None*");
> rename("counted"+t1);
>
> ______________ end cut ___________________________
>
>
>
> Fernando Sales wrote:
>> Mike,
>>
>> if you have a program that segments and identify the cells in each
>> slice of
>> the stack, you can generate a binary mask and count the number of
>> "islands"
>> of white pixels (suppose that the cells are white and the backgroung is
>> black). I've developed a plugin which implements a labelling algorithm to
>> identify different objects in a binary scene. Then, this way you can
>> count
>> the number of cells slice by slice.
>>
>> Cheers,
>> Fernando
>> On Fri, Apr 11, 2008 at 3:54 PM, Mike Myerburg
>> <myerburg@gmail.com> wrote:
>>
>>  
>>> Hi-
>>>
>>> I study polarized cells that form a pseudostratified epithelial layer on
>>> filters.  I am trying to make a plugin that will count the # of nuclei
>>> present in a stack.  Because the cells are not a monolayer, I cannot
>>> accurately count them by making an zprojection and then do standard
>>> automated counting (the nuclei are occasionally on top of each
>>> other). It
>>> seems that it "should" be possible to make a plugin to analyze the
>>> nuclei in
>>> 3D and then count the number within a stack.
>>>
>>> Has something like this already been made?  Any suggestions?
>>>
>>> Cheers, Mike
>>>
>>>    
>>
>>
>>
>>  
>