This project is getting on my nerves!


#1

Hey there,

I’m trying to create a pipeline to count and measure axons in a nerve cross section. I just can’t get it to identify objects correctly. I’ve tried a couple of pipelines from other help posts that were similar, but none of them have the full nerve cross section, and no matter how much I tweak them, I can’t get them to identify the objects that I want.

I tried identifying the nerve as a whole (so I could then mask the image), and it will put an outline around it, but won’t count it as an object. I’ve tried unmixing colors, greyscale, thresholding, and I just can’t get it to work. If I can get it to identify the myelin sheath, then I think I can get it to measure the inner axon bit, but I can’t seem to get that right. Either it’s breaking the myelin sheaths into too small pieces, or it’s identifying the outer membrane of the nerve as some of the myelin sheath. At this point, I’ve added so many modules, trying to get the right combination of things, that I’m just confusing myself and going in circles.

I would just like some advice on how I should approach this. I think the real difficulty lies in that the inner part of the axons is slightly darker, so getting it to threshold to exclude that, but still count some of the smaller/less bright cells.

Should I edit the image beforehand to just exclude everything but the axons (before even putting it in cell profiler), or is there some easier way that I’m missing?

Currently our lab has been using (Fiji is just) ImageJ to go through each image one by one (so clunky and time consuming), often needing to manually add/remove neurons to the count, and I was hoping to streamline things by creating a pipeline. That way, once we have all the images stitched, we can just add them to the pipeline and analyze them.

Below are all the pipelines I’ve attempted to use (including the one with a billion modules all trying to get the magic image) as well as the test image I’ve been using.

DLpipe.cppipe (9.7 KB)
NeuronTest2.cpproj (402.1 KB)
NeuronTest3.cpproj (408.5 KB)
NeuronTestPipeline.cpproj (419.8 KB)


#2

Alternatively, is there a way to filter objects by “circularity?” I think if I can do that, I can get the measure of the axons, while still excluding everything I don’t want.


#3

There are definitely ways to filter objects by certain measurements of shape (depending on exactly what you mean by that it could be any of a few different specific measurement, so I’d look at the help for MeasureObjectSizeAndShape to try to find one you think is best) using the MeasureObjectSizeAndShape and FilterObjects modules.

I think you’re right though that the fact that the interior of the axons is roughly the same color as the space between them is going to make it hard to distinguish based on threshold alone; I wonder if this might not be a good case for combining CP with ilastik; you could make classes for “Myelin Sheath”, “Background”, “Axon Edge” and “Axon interior”. Once you had your probability maps in ilastik you could export them into CP for a simple identification-and-measurement pipeline.

Good pun, by the way :slight_smile:


#4

:+1: for Ilastik. Even if you can just get a background class, this would make a nice mask for isolating the axons.


#5

I haven’t even heard of ilastik before. I suppose I can give it a go, since it sounds simpler than what I’VE been attempting. I’ve been attempting to mask and re-mask and invert and I get SO CLOSE but then not quite. There’s always a few pieces that register as axons that aren’t.

Do you have to go through each image with Ilastik, or is it like cell profiler, where once you “teach” it your specifications, you can run your images through in a batch, and then export those in a batch? Where would all the classifications integrate into CP? I can see how you could make a mask, since you can use an image for a mask, and just have the map as your reference image.

Thanks so much for your suggestion! With any luck this could cut down hours of endless pointing and clicking.


#6

Do you have to go through each image with Ilastik, or is it like cell profiler, where once you “teach” it your specifications, you can run your images through in a batch, and then export those in a batch?

You can train it on a few representative images (try to cover as much variation in shading, lighting, fiber size, staining, etc, in your training set- better to train on extra images than to have the training come out wrong!) then once ilastik has come up with a model you can run it on the larger batch of images. Even when you’re training though, each image will “learn” from the other ones so it should only take a little annotating on each image to come up with a good model that works across all of them.

Where would all the classifications integrate into CP?

You export the classification images as TIFs, which you’d then load into CP essentially as extra “channels” of your original image- depending on what you wanted to do, you could even omit the original image entirely and just load the classifications (though it’s often nice to have both, even if just for the ability to overlay your final objects on the original image to make sure you agree with the segmentations).

I’ve been attempting to mask and re-mask and invert and I get SO CLOSE but then not quite. There’s always a few pieces that register as axons that aren’t.

FWIW there is a CP module called EditObjectsManually, that would let you throw out the junk but keep the ones that you want. Everything you’ve been describing so far seems very reasonable, so I trust you’re doing the right things, but I’ll give you a word of caution I give pretty frequently on the forum - when possible, try not to let the perfect be the enemy of the good. Unless there’s reason to believe the few small errors are really gonna throw off your conclusion, you’re often better off spending 5 hrs getting an analysis to 95% correct and having 15 hrs to do a few extra experiments than spending 20 hrs getting it to 99% correct. Just my $0.02.

All of that being said, hopefully ilastik will solve your issues and allow you to get a really great segmentation! Good luck.


#7

What kind of accuracy are you currently getting?

I’m not sure what you want to count :slight_smile: but if you mean those round object then you can try CellStar plugin (http://cellstar-algorithm.com).
I’ve used it in a pipeline and got something like this:
NeuronCellStar.cppipe (5.6 KB)

As to filtering you can use CellProfiler Analyst. Basically you put segmented objects to true/false bins and it figures out how to generally distinguish them.
Then you can use these rules in FilterObjects in CellProfiler.

For more detail on CPA usage you can check:


#8

Wow. That’s beautiful! Better than any of my pipelines. The trick is trying to get it to ignore that outer membrane of the nerve bundle. I’ll run this by my PI and see what they think, since it might be “close enough” for our purposes.

I’ve been playing with ilastik, but I have version 1.2 instead of 0.5, since 0.5 won’t work on my computer, and I can’t get it to cooperate with CP.

On here: https://github.com/CellProfiler/CellProfiler/wiki/How-to-use-Pixel-Classification-in-CellProfiler
They suggest exporting the probability map/Simple segmentation as an image, but I don’t know if they mean a .tiff or a .jpg or what. I can’t even get Ilastik to properly export a .jpg anyway. They link back to a post on this site, but unfortunately, due to the way they loaded their example, I can’t access it anymore to try and get an idea of how they did it.

Do you use the “Load Images” module so you can keep your original images separate from your ilastik pixel classification images?


#9

To ignore that outer membrane you can prepare ignore mask image and then filter out result using MaskObjects or using IdentifyYeastCells internal ignore mask feature.

Mask image can be one for all analysis (prepared as image) or per image (generated for example by IdentifyObjectsManually - which allows you to scribe a shape to keep/ignore).