Login  Register

Re: Count cells in stack?

Posted by Mike Myerburg on Apr 16, 2008; 12:49pm
URL: http://imagej.273.s1.nabble.com/Count-cells-in-stack-tp3695075p3695080.html

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
>>>
>>>    
>>
>>
>>
>>