Cell segmentation on cell borders (rather than nuclei) - trouble with cellprofiler

Sample image and/or code

original image:

Background

We are trying different IF markers of cell membranes to help with segmentation (otherwise impossible), and this one looks absolutely amazing! This is in the liver, where multi-nucleated cells mean that nuclei-based segmentation does not work.

Analysis goals

Segment my cells

Challenges

When I try to segment in cell profiler, I’ve not been able to find settings that satisfactorily segment my cells, even though the edges seem obvious (dark black lines in the image above). For example, about one third left from the right edge, one third down from the top edge are three cells that have randomly been divided into 2 or 3. Since most segmentation is done using nuclei, these are the steps I took which might be part of the problem.

  1. Max projection
  2. split channel to only my border marker
  3. Negative of image

Settings: Here are setting used for the IdentifyPrimaryObjects segmentation above. But, I have tried many combinations of threshold strategy, method, smoothing, correction factor, window sizes. It seems the problem has to do with the declumping, but I haven’t been able to improve the segmentation much better than the image above. I tried making a binary mask in ImageJ and the segmenting algo still draws lines through the middle of cells!

Thank you for considering!

Original image

Adding in the CellProfiler tag and @bcimini
Though I can guess that the first request will probably be your actual pipeline file.

May as well mention the office hours thing as well:

the pipeline
membrane_segmenting.cppipe (5.1 KB)

thank you!

1 Like

From what I can tell looking at your image, the problem is that the threshold being chosen is too low; this is maybe not surprising, given that your image is mostly foreground, with very little background, whereas most algorithms expect a balance of both. Your options are, in order of difficulty to execute + reliability once executed to work across many images (easiest and most reliable on top):

  1. Turn your Threshold Smoothing Scale down to 0
  2. Try a different thresholding algorithm- maybe 3-class Otsu with middle class to background, or MCE?
  3. Try a pretty high threshold correction factor, ie greater than 2; whatever it takes for the dark lines to no longer be included in the thresholded area
  4. Use ImageMath to apply some sort of transformation to the image, such as squaring it, to increase the difference between the bright and dark areas (then return to 2)
  5. Find some way to threshold and mask out specifically the dark areas, such as by inverting the image in ImageMath, doing a Threshold there, and then doing a MaskImages module onto your original image before doing IPO.

Good luck!

3 Likes

Dear Marc,

Could this material be helpful at all: Images and words, Emmanuelle Gouillart's blog - A tutorial on segmentation?

I’m happy to dive into the Python-specific or scikit-image–specific details if you are interested.

Cheers,
Marianne

2 Likes

Also, could cellpose do anything for you? @mssher07

I just read about it in this reply by @jni :wink:

1 Like

Hi @mssher07
Hopefully I won’t be detracting from any of the other great answers here, but your problem looked similar to a type of analysis I have recently improved upon for one of my plugins so I thought I could offer an alternative approach. Please feel free to ignore me and my suggestion, especially if you would prefer not to try a pure ImageJ approach, which my suggestion is.
Adapting a muscle morphometry plugin that I created, I was able to get this segmentation of your sample:
N2_NEG-MAX_border-after_segmentation
It’s not perfect, but I think it’s reasonable.

You can find my plugin in this googledrive folder. You just need to place the ‘Muscle_morphometry-0.0.4.jar’ file in the ImageJ/Fiji plugins folder to install the plugin. It can then be accessed via ‘Plugins>Muscle morphometry’.

To get the above, I ran the plugin with these settings, when prompted (2,1,8,4). I would uncheck the automatic export to .xlsx and instead select to populate the ROI manager.
Then at the first prompt to select the border window, run this macro on the image:

run("Minimum...", "radius=3");
run("Kuwahara Filter", "sampling=5");
run("Gaussian Blur...", "sigma=4");
run("Subtract Background...", "rolling=35 light");

setMinAndMax(0, 222);
run("Apply LUT");

run("Gaussian Blur...", "sigma=5");
run("Maximum...", "radius=1");
run("Unsharp Mask...", "radius=10 mask=0.8");
run("Invert");

//optional erode below... try with or without
run("Minimum...", "radius=3");

and before pressing Okay for the first time. Then select one of the blank windows for your nuclei channel, before pressing Okay again.

Anyway, sorry again if this seems like spam, since it is not cell profiler related. Please feel free to ignore me. I can also delete this post if asked.

Kind regards.

2 Likes

Thank you all for the feedback! I am still working on this and have been implementing some of your suggestions.

The end goal is to output this for FISH-QUANT, which requires a cell profiler MASK file. I’m sure there is a way to convert some of these non-cellprofiler solutions to the same format, but I’m not facile enough with these formats yet to know how hard that would be…

@bcimini THANK YOU for taking a look at this. I tried 1-3 without significant improvement, but I was able to make a bit of headway by customizing the “size of the smoothing filter” for the declumping. It seems this was responsible for many of the silly segmentations that crossed nuclei. I’ll post an updated look once I make some more headway.

@antinos - this is incredible. On my to do list is to play with your imageJ plugin, as it looks superior to even my further optimized cellprofiler attempts. I’d just have to go through cell profiler eventually, but I think i could probably figure that out…

@mkcor - thanks for your suggestions as well. It’s reassuring (in your first link) to realize that this cell border problem is not as trivial as it first appears. If all else fails, will look deeper into the scikit-image approach

Thank you all again, will post results soon

From my understanding of reading the FISH-QUANT documentation, I believe that FISH-QUANT requires a .tif file where the pixels for each segmented object have different values from each other (all of the pixels that are part of nucleus #1 have intensity value 1, pixels for nucleus #2 have intensity value 2, etc.). This format is a highly generalizable format – many programs should be able to output this type of image as a mask. Good luck!

From the FISH-QUANT documentation:

1 Like