Automated diameter measurements of a stack

I have a few video file of a vessel undergoing radial stress cycles that I need to analyse. I would like to track the vessel diameter through time. This is simple enough to do for a single image by drawing a line and using the measure function, however, these video are each approximately 6 seconds long recorded at 30fps. Is there a way to automate this measurement for the sake of time? Here is a frame of the file with a line drawn across the diameter to illustrate what I am trying to measure.


The trick will be to set up an automated way to measure the vessel diameter… You can read up on Segmentation here. There is also a workshop on Segmenting with Fiji.

Once you have that for a single slice - you can apply that workflow for each slice for the whole stack. You will have to get into some scripting - and if this sounds scary - don’t worry! You can use the ImageJ1 macro language - recording your steps as you go using the Macro Recorder. Some other helpful sites to get you started:

Hope this helps!

eta :slight_smile:


@etadobson - Thanks so much for your help! The workshops on Segmenting + Scripting were very helpful for getting started.

I’m still pretty stumped on actually measuring the diameter of the vessel without manually drawing a line ROI as indicated in the original post. I’ve been able to segment, binarize, and skeletonize the image, but still haven’t found a way to recognize the edges of the vessel and measure the vertical distance between them.

I did find the relevant forum post below, but am not sure how to apply any of the suggestions to this particular problem:

Any suggestions for moving forward? Thanks!

Did you look into the MorphoLibJ’s Geodesic Distance Map plugin as suggested by @iarganda in his response on that post?


Yes, I have successfully created the Geodesic Distance map from the mask and the skeletonized image, as shown below:

However, when trying to use the Analyze > Geodesic Diameter function within the MorphoLibJ plugin, it is failing to complete the analysis and I am getting the following error [even when the ‘Distances’ option is set to Borgefors (3,4)]:

“Could not compute geodesic paths. Try using Borgefors weights.”

Since it isn’t completing successfully, I haven’t been able to see the Overlay Result or get the results exported to the ROI Manager.


Ok. I would say smoothing out your binary mask (the left-most image) would help a great deal… Your skeletonization is picking up every single little variation in your vessel surface - which is what is does do - but for sure, you need fewer and more regular branches to calcuate the diameter. Would you be able to post an original image here? And also what exact steps you take to create the binary mask which you then use to skeletonize?

You can look at binary morphological operations to help you in this, such as erode, dilate, fill holes, etc. There are a few links on this slide from the Segmentation workshop.

eta :slight_smile:

1 Like


Here is the original image:

These are the steps I’m currently running on the image (note that this is modified slightly from the images I posted earlier):

run("Threshold..."); //setting this manually from 0-40% for this imagel
run("Create Mask");
run("Keep Largest Region");
run("Fill Holes");
setOption("BlackBackground", false);
run("Geodesic Distance Map", "marker=skeleton-largest-1 mask=mask-largest distances=[Borgefors (3,4)] output=[32 bits] normalize");
run("Geodesic Diameter", "label=mask-largest-geoddist distances=[Borgefors (3,4)] show image=mask-largest export");

With these steps, I am getting a much smoother skeleton already - but the Geodesic Diameter function is still failing

ok @cfbare… Perhaps @iarganda can give you some help regarding the Geodesic Diameter function? I have not used it myself.

Running your macro on the image you provided … I see there is a shadow in the background of your image. To try to even out that background issue - you could add this to the beginning of your code:

image = getTitle();
run("Duplicate...", "title=background");
run("Gaussian Blur...", "sigma=600");
imageCalculator("Subtract create 32-bit", image,"background");
selectWindow("Result of " + image);
// now you create the 8-bit image, so the rest of your code goes here...

Hope this helps a bit!


1 Like