Re: help with 3D segmentation - update

Posted by TimFeinstein on
URL: http://imagej.273.s1.nabble.com/help-with-3D-segmentation-tp5014798p5015210.html

Hello Aryeh and others,

Thank you!! The droplet finder plus Gaussian blur and background
subtraction works extremely well for nucleus detection in 3D tissue.  I
put together the script at the bottom based on yours to get the most
reliable results with our data.  The live preview was essential for
calibrating the variables correctly.

Some follow-up questions:

Fiji can do Gaussian blur and median filtering in 3D.  Is there any
advantage to doing it that way?  Does the extra time offset any precision
improvement?

Also, I am having trouble scripting the final quality control step.  Right
now I export the results, filter outliers in Excel and re-import the X and
Y positions via Import>XY CoordinatesÅ   That works pretty well when I
overlay it on a max intensity projection, although it misses nuclei
sitting on top of each other in the stack. It would be nice to preserve
the masks from the live preview window as a stack image.  Alternatively I
wonder whether it would be possible to draw a small sphere centered on
each XYZ centroid.  Say, make a stack with spheres and merge that with the
data stack using color merge, with spheres in red and data in green. You
could pretty quickly judge which nuclei are inappropriately detected.
This is just an idea; drawing a sphere in a stack centered on a designated
XYZ position is outside my current abilities.

My version of the nucleus detector (40x 1.2 water lens; 0.11 x 0.11 x 0.5
um pixels):

dupTitle=getTitle
BG = getNumber("Enter background:",80);
run("Subtract...", "value=BG stack");
run("Despeckle", "stack");
run("Median 3D...", "x=2 y=2 z=2");
run("Gaussian Blur...", "sigma=0.70 scaled stack");
run("32-bit");
run("Brightness/Contrast...");
run("Enhance Contrast", "saturated=0.35");
run("DF_Filterstacker", "maximal_feature_size=8 minimal_feature_size=3
z/x_aspect_ratio=5.000 radius_x=2 radius_y=2 radius_z=2 invert
image=[BP_"+dupTitle+"] mask=[WS_BP_"+dupTitle+"] area_threshold=0.150
maximum_threshold=0.30 connect_threshold=0.40 slice=1");

All the best,



Tim

Timothy Feinstein, Ph.D.
Research Scientist
University of Pittsburgh Department of Developmental Biology





On 11/13/15, 6:04 AM, "ImageJ Interest Group on behalf of Aryeh Weiss"
<[hidden email] on behalf of [hidden email]> wrote:

>This last week I focused mostly on the 3D-watershed approach.
>Updates are interleaved below.
>
>On 08/11/2015 9:10 AM, Aryeh Weiss wrote:
>> Further on my adventures using the DoG function:
>>
>> I mentioned that the DoGPeaks function appears to find minima as well as
>> maxima. I decided to go to the Difference of Gaussian function
>>
>>http://javadoc.imagej.net/Fiji/mpicbg/imglib/algorithm/scalespace/Differe
>>nceOfGaussian.html#DifferenceOfGaussian(mpicbg.imglib.image.Image,%20mpic
>>bg.imglib.image.ImageFactory,%20mpicbg.imglib.function.Converter,%20mpicb
>>g.imglib.outofbounds.OutOfBoundsStrategyFactory,%20double[],%20double[],%
>>20B,%20B)
>>
>> Here I see that it explicitly states that it extracts local minima and
>> maxima of a certain size. I wonder if I can get only the maxima fro this
>> function.
>>
>
>Jan Eglinger posted the answer to this. Here is what he wrote:
>-----
>You have to go one step further: the `DifferenceOfGaussian` class has a
>`findPeaks` method that gives you a list of `DifferenceOfGaussianPeak`s.
>
>In its Javadoc [1] you find the methods:
>     boolean isMin()
>     boolean isMax()
>that you can use to differentiate between minima and maxima.
>
>I modified your script to only get the maxima:
>https://gist.github.com/imagejan/7cc228b9a5e57cce44a0
>
>Here's what I changed:
>https://gist.github.com/imagejan/7cc228b9a5e57cce44a0/revisions
>-----
>
>This enables the threshold to be set lower, without picking up the minima.
>
>> Among its parameters are Converter, OutOfBoundsStrategy (among others).
>> I did not understand how to use these classes, so I wonder if someone on
>> this list can tell me how to use them, or even better, point me at the
>> documentation that might help (the class definitions in javadoc were not
>> enough for me).
>>
>
>Jan also added the following:
>-----
>Albert's excellent tutorials unfortunately make use of the
>now-deprecated ImgLib1 code that was superseded by ImgLib2 [2].
>
>Jean-Yves Tinevez's TrackMate plugin is a great example how to use
>ImgLib2. It's `LogDetector` [3] and `DogDetector` [4] classes show how
>to detect spots using ImgLib2 implementations of LoG and DoG.
>
>I added a script to the ImageJ wiki illustrating how to use
>`DogDetector` from a Python script:
>http://imagej.net/Jython_Scripting#Find_peaks_in_a_3D_image
>-----
>
>I did not have a chance to try this, because I focused on the watershed
>approach (see comments below).
>
>> Thank in advance.
>> --aryeh
>>
>>
>> On 05/11/2015 12:58 PM, Aryeh Weiss wrote:
>>> This is an update on the problem I posted.
>>>
>>> First, thanks to the people who replies with suggestions. From these, I
>>> am now following up on two of them.
>>>
>>> 1. Albert Cardona suggested trying the 3D (actually multi-D) difference
>>> of Gaussians (DoG) filter. This looks promising, plus it introduced me
>>> to imglib. It works great on isolated cells (actually, everything works
>>> great on isolated cells) and seems reasonable for my image, but still
>>> needs work. because I have such a dense collection of nuclei, it
>>> sometimes detects dark blobs, which are actually an approximately
>>> cell-sized island within a sea of nuclei.
>>> Albert's sample code  displays the result in 3D using the 3D viewer.
>>> Unfortunately, java3D does not work in java 1.8, and in Java 1.6, while
>>> the java3D test works, the code that generates the 3D view fails --
>>>that
>>> will go into a separate thread.
>>> The net result is that I can mark the centers of the nuclei (which is
>>> why it look promising) but I cannot visualize it in 3D to see if it
>>> really looks right.
>>>
>>> 2. Thomas Boudier suggest some 3D bandpass filtering followed by a
>>> seeded watershed. I will work more on finding the right parameters for
>>> this approach  after I finish with the DoG approach.   One problem is
>>> that the resolution in Z is much lower that in X-Y. As a result, the
>>> watershed does not separate the nuclei along Z. It is not clear to me
>>> why the DoG does.  However, I still need to learn to to use the output
>>> of the watershed -- I may not be interpreting the output correctly.
>>>
>
>I found that I got a very good segmentation (ie, marking of the nuclei)
>by using the watershed in the droplet finder plugins. Or more
>accurately, using the droplet finder workflow which is run by
>Plugins>Droplet Finder>DF_Filterstacker
>
>The macro recorder enabled me to script it.
>
>// The code to get the file and parse
>// the filename and image title has been left out.
>
>run("32-bit"); // DF-Bandpass wants 32 bit input
>
>// The median, rolling ball filter, and Gaussian blur
>// greatly improved the accuracy
>run("Median...", "radius=2 stack");
>run("Subtract Background...", "rolling=50 sliding stack");
>run("Gaussian Blur...", "sigma=1.5 scaled stack");
>
>// macro recorder created this. This is a long command, so if you
>// cut and paste, you may have to reassemble it
>run("DF_Filterstacker", "maximal_feature_size=15 minimal_feature_size=7
>z/x_aspect_ratio=5.000 radius_x=2 radius_y=2 radius_z=2 invert
>image=[BP_"+dupTitle+"] mask=[WS_BP_"+dupTitle+"] area_threshold=0.300
>maximum_threshold=0.3 connect_threshold=0.80 slice=5");
>IJ.renameResults("Results");
>IJ.renameResults("Particle Results");
>
>
>This script produces a table called "Particle Results", with (among
>other things) the X, Y, and Z coordinates of the objects.
>
>>> I recently got access to Imaris (basic) with a spot detector. It does a
>>> decent job, but since I don't have it on my computer, I plan to solve
>>> this with ImageJ.
>>>
>>> When I have something that works and that I can visualize, I will post
>>> it for the benefit of other who, like me, have to muddle their way from
>>> 2D to 3D.
>>>
>
>In order to visualize the results, I have a python script to read the
>Particle Results table and produce a set of point ROIs that can mark the
>original image.
>The i can flatten the image and display this with the 3D Viewer (Java
>1.6 only).
>
>"""
>This script converts the output of the droplet finder plugin (Paticle
>Results)
>to a set of point ROIs whcih can be used to mark the drops (in my case,
>nuclei)
>on the original image.
>
>Input: Particle Results table from Droplet Finder
>Output: An ROI Manager populated with point ROIs whose coordinates
>         correspond to the list in the table.
>
>Bugs to fix: If the ROI Manager is open when the program is run,
>rm.addRoi fails with a null pointer error.
>"""
>
># Does not require auto-import
>
>from ij import IJ, WindowManager
>from ij.plugin.frame import RoiManager
>from ij.measure import ResultsTable
>from ij.gui import PointRoi
>
>dfTitle = "Particle Results"
>IJ.renameResults(dfTitle , "Results")
>
>rt = ResultsTable.getResultsTable()
>
>pos = []
>
>for i in range(rt.size()):
> pos.append([rt.getValue("position_x",i), rt.getValue("position_y", i),
>rt.getValue("position_z", i)])
>
>for i in range(rt.size()):
> print pos[i];
>
>print len(pos)
>
>dfTitle = "Particle Results"
>IJ.renameResults( "Results" , dfTitle )
>
># I do not know why this does not prevent the null pointer error
># which I get if the ROI Manager is open when this script is run
>if "ROI Manager" in WindowManager.getImageTitles():
> WindowManager.getWindow("ROI Manager").close()
>
>rm = RoiManager()
>rm.show()
>
>for p in pos:
>   cellRoi = PointRoi(int(p[0]),int(p[1]))
>   cellRoi.setPosition(int(p[2]))
>   rm.addRoi(cellRoi)
>
>rm.runCommand("Show All without labels")
>
># end of script
>
>I actually created two images -- one is the original, and the second is
>a blank image with the point ROIs flattened into it. Then I overlay them
>with the 3D viewer and increase transparency of the data to see the
>marks. What I really want to do is make the nuclei into surfaces and
>then "peel" them away to reveal the marks. I have not yet figured that
>out, and the surface rendering takes a really long time.
>
>One problem I have is that sooner or later, the 3D Viewer menus get
>grayed out (though mouse clicks in the 3D Viewer window still work).
>The I have to close it and start again. I have not been able to
>associate this with a reproducible set of actions.
>
>
>I hope this is useful
>--aryeh
>
>--
>Aryeh Weiss
>Faculty of Engineering
>Bar Ilan University
>Ramat Gan 52900 Israel
>
>Ph:  972-3-5317638
>FAX: 972-3-7384051
>
>--
>ImageJ mailing list: http://imagej.nih.gov/ij/list.html

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