Analyze Skeleton 3D object ID

Dear @iarganda and Image J Community,

First off, thank you @iarganda for your work. I am a PhD student and this plugin is making my work possible. This particular project is for a poster in this years’ Society for Neuroscience conference.

I am using Analyze Skeleton to measure nerve terminals in a confocal image stack with fluorescence. I would like Analyze Skeleton to produce an image stack with numbers that identify the structure with the data.

This is my work-flow:

I measure the objects with Cell Object Counter 3D. This plug-in produces new image stacks that give a number for the structure identified so I can match the actual structure with the data. I am then taking one of these image stacks, skeletonizing it, and running it through Analyze Skeleton. Analyze Skeleton is recognizing the same 13 objects and measuring them. However, they are out of order when compared to Cell Object Counter 3D.

Is there any way to have Analyze Skeleton produce an image-set that shows the object ID number in the stack. I was hoping the “Skeleton-labeled-skeletons” image stack would have numbers that would identify the structures but I did not see it.

If we could get ID numbers within the image stack then we could organize the match the data from Analyze Skeleton with Cell Counter 3D. It would be great to match the data up so we can have volume, surface area, mgi and length!

Thank you for all of your hard work!

-Michael Anderson

I found on the Image J page for Analyze Skeleton that the “Display labeled skeletons” option is supposed to display the skeleton ID next to the skeleton but I did not see any numbers in the “labeled skeleton” image stack generated by Analyze Skeleton. I wonder why I am not seeing the Skeleton ID number. Could it be because I am using an image stack?

Display labeled skeletons. An extra output image will be displayed containing each skeleton labeled with its corresponding skeleton ID.

Hello @Michael and welcome to the ImageJ forum!

No, the skeleton IDs are the voxel values in the labeled-skeletons image (you should see them with a different color based on the LUT). See for instance the following result on the skeletonized blobs image:

image

In that image, the skeleton with ID 1 has voxels with intensity value 1.0, the skeleton with ID 2 with intensity 2.0 and so on. Does it make sense to you now?

That being said, the skeleton IDs (or labels) output by AnalyzeSkeleton most probably won’t match the ones provided by the Cell Object Counter 3D because the labels depend on the order of visit of each voxel. What you can do, is to assign the AnalyzeSkeleton IDs to your original binary image using something like Marker-controlled Watershed:

Input images:
image

Plugin settings:
image

Output with Fire LUT:
image

1 Like

Hi @iarganda,

Thank you for the detailed information.

I was hoping to find a streamlined way to match the data from the two plug-ins.

I am not sure if/how the value of the pixels for an object, in the Branching Information window, may help in the matching of the measurements between the two plug-ins. Unfortunately, the marker-controlled watershed would not work properly with the objects in my image stacks.

My current work-around is to use the Object map image produced by Cell Counter. Each object in that plug-in is chronologically correlated by pixel intensity. Object 1 can be isolated by the threshold of [1, 1], and object 2 can be isolated by the threshold [2, 2], and so fourth. For example, I isolate and save Object 1 (threshold [1,1]), skeletonizing, measuring the object in Analyze Skeleton, and copy/pasting the data and matching to Object 1 data from Cell Object counter.

If you can think of a better strategy will you please let me know?

I am relatively new to using 3D plugins.

Thanks again for your help,

-Michael

Why not? What is the problem there?

You shouldn’t need to do that. Why don’t you post here (or upload somewhere) an example of your Object map image so we can find an easier solution?

Thank you @iarganda,

I just discovered that I wasn’t using the watershed plugin correctly when I first tried to follow your directions. I was able to successfully use it but I am not sure how this works or how it will solve my issue. I was able to match my blobs with the labeled-skeletons and then take the resulting image, skeletonize it, and run it through Analyze Skeleton and it gives me the correct number of objects but I am not sure if the data is matching. Thank you for your patience because I am very new to many of these plugins.

Here are two images of the numbered Object maps combined with Z-Project into one image:

.

These are nerves traveling mostly longitudinally along the z axis. I am prepping and skeletonizing these images before running them through Object Counter. In object counter they are thesheld for size/intensity and assigned an ID with an option to have the number assigned to the object in the image.

As of the last few days I have been collecting data to present as mean volume and length per field-of-view or group. I will be matching the columns using the slow method. It works but takes time. In the future it would be great to easily match the data to organize the data-points discretely and potentially get a better feel for these nerves.

Any advice is greatly appreciated and I will certainly give you credit.

Thank you,

-Michael

Hello @Michael,

I’m confused now. Why do you run the Object Counter on the skeletonized images? What do you get from Object Counter that you can’t obtain from AnalyzeSkeleton then?

Sorry for the confusion. I do this:

  1. skeletonize stack
  2. reopen original stack and merge
  3. run through Object Counter
  4. use Object map to threshold for objects
    • threshold 1,1 is object 1 and so on
  5. skeletonize each object and Analyze Skeleton
    • this assures that I am getting the same measurements for volume as I am for length

I would love a high-throughput way of automatically matching the exact structures between the two plugins but I do understand they are operating in different ways.

Hello @Michael and sorry for the late answer:

If you merge the skeletonized stack with the original stack, don’t you get the same original stack?

OK, let me reformulate my question then, do you need any measurement taken by the Object Counter plugin? If not, you can directly work with the skeletonized stack and the output images from AnalyzeSkeleton.

Hi @iarganda,

No problem, thanks for your help!

It works if you use “image calculator”. If you “color -> merge” then it will not work. This helps to consolidate objects by creating a backbone for them based on distance and pixel intensity.

This is a great question. When measuring these nerves the length measurements seem most important. This helps a lot but I eventually want to correlate “integrated density” and “mean-grey-intensity” with length measurements. This would allow evaluating receptor concentration per object.

Another benefit is in the post-thresholding of the data points. By having measurements of volume and surface area along with length measurements we can set up post-thresholds to exempt artifacts based on known parameters.

For this poster I am using length measurements to look at the frequency distribution of the objects. I then individually matched 6 nerves between Analyze Skeleton and Object Counter to show with the reconstructed mesh, for nice poster images.

Thanks again for your help,
-Michael

I’m not sure what you need the merged image for. Can you please post here an example of such an image and why you need it?

OK, so you need both the original thresholded image and the skeleton one. Can you please post here (or upload it somewhere) one of your images so I can make a macro or script that does what I believe is what you need?

Hi @iarganda,

Absolutely. I will do it this weekend. I have an oral presentation tomorrow morning and am busy preparing for that but will do it either this Saturday or Sunday.

Thanks for all of your help!!

If you are going to this year’s Society for Neuroscience conference you should stop by my poster.

-Michael

Dear @iarganda and Image J Community, I also want to thank you all for your work. I am a PhD in Material Science and I am using Skelenize and Analayse skeleton (2D/3D) in order to analyze the porosity of my samples, and calculate a pore size distribution and the tortuosity among others.

I am contacting you because some of my supports have more then 2^15 objects (pores) and they can not be analyzed. Is there any possible solution to analyze these complex porosities? I tried to re-scale the scans and to crop into two the scans, both to split the data but nothing worked. A window about nullpointererror appears every time or the message about more than the 2^15objects …

Thank you very much in advance,
Alejandra

In principle, the limit is 2³¹ - 1 skeletons. Can you post here the error you get?

The skeleton IDs is as same as the voxel values in labeled-skeletons image. Only the skeleton with voxel value: 0 (depending on LUT configuration, white or black color) will be shown with ID: n, with n being the total number of separated skeletons. so if you have 3 separated skeletons. your IDs will be 1, 2 ,3. skeleton with ID 1 will be blue, with ID 2, will be red and with ID 3 (will be white or black)