Length measurements: How to measure length of biological curved structures

imagej

#1

Hi everybody,

I’m starting analysing images in Fiji and I have a question about this. I work with the digestive tube of termites and I’m looking for the best way to measure its length as I show in the image above. The problem is because a digestive tube is no straight structure, actually I think of using segmented line, but I also need to be sure of this measure is being real because if I repeat measure of same sample I’m risking increasing the length variability. Do you know any way to automatize each small point of the segment line in the middle of the digestive tube width?
Thanks so much for your help! :slight_smile:


Automated diameter measurements of a stack
Dendritic Beading Analysis
Counting tapeworm segments- please help
Analyzing cell layer thickness
Selection of Threshold value
Analyzing cell layer thickness
#2

Please have a look at the recent discussion about length measurements:

See also the Skeletonize3D plugin: http://imagej.net/Skeletonize3D#Related_work

You can preprocess and extract the digestive tube with the Color Thresholder or you can use a segmentation plugin, e.g. the great Trainable Weka Segmentation (again from @iarganda).


#3

Thanks for your suggestions; I tried the pre-process with Thresholder however the saturation of the image is a little bit bad, I had as result a binary image with other non-important structures; so I processed to analyse skeleton, there’re more branches and I just need largest length .

I also tried with TWS, this way was better, but I have a problem with java, because when I run the train classifier there’s space memory error. I think is because my files are the .ZVI stacks.

So finally, I’m trying to make a selection of the interested structure, then I run “analyse skeleton” on that selection. The result is not bad, but is a semi-automatic method, because for each hyperstack I have to create a new freehand selection.

Note: length with analyse skeleton = 4962.631 µm
Segmented line length = 4736.778 µm

Do you have any idea about “to make better binary images”? :slight_smile:


#4

I would give the trainable segmentation a second try.

Please adjust the memory of FIJI to enable more RAM:

http://www.openmicroscopy.org/site/support/bio-formats5.1/users/imagej/managing-memory.html

Eventually choose another classifier. RandomForests can be very memory intensive:

Here a nice video on YoutTube:


#5

Thanks for this information
I’ll try again TWS after adjusting the memory of Fiji,
I had watched this video as tutorial TWS, Indeed, when I used the polygon classifier the process was slow


#6

You can segment that tube quite well using the Color Threshold command. Here is an example macro:

// @File imageFile

open(imageFile);

// preprocess/smooth things a little bit
run("Gaussian Blur...", "sigma=5");

// Color Thresholder 2.0.0-rc-47/1.50i
// Autogenerated macro, single images only!
min=newArray(3);
max=newArray(3);
filter=newArray(3);
a=getTitle();
run("HSB Stack");
run("Convert Stack to Images");
selectWindow("Hue");
rename("0");
selectWindow("Saturation");
rename("1");
selectWindow("Brightness");
rename("2");
min[0]=0;
max[0]=32;
filter[0]="pass";
min[1]=0;
max[1]=255;
filter[1]="pass";
min[2]=0;
max[2]=255;
filter[2]="pass";
for (i=0;i<3;i++){
  selectWindow(""+i);
  setThreshold(min[i], max[i]);
  run("Convert to Mask");
  if (filter[i]=="stop")  run("Invert");
}
imageCalculator("AND create", "0","1");
imageCalculator("AND create", "Result of 0","2");
for (i=0;i<3;i++){
  selectWindow(""+i);
  close();
}
selectWindow("Result of 0");
close();
selectWindow("Result of Result of 0");
rename(a);
// Colour Thresholding-------------

// smooth out the mask a little
setOption("BlackBackground", true);
run("Dilate");
run("Dilate");
run("Dilate");
run("Fill Holes");

// select only the big tube
run("Analyze Particles...", "size=5000-Infinity add");

// close the mask image
close();

// open the main image again
open(imageFile);

// select the region
roiManager("select", 0);

I built this using the Macro Recorder as well as the “Macro” button of the Color Threshold dialog.

Here is the result:

You could probably get the white part of the tube too by adjusting the hue range.

Presumably the skeletonization, measurement, etc., is not such a big deal once you have a selection around the tube?


#7

Thanks so much for your help!

With a little bit variation in your macro (files .zvi), I had a similar result for several images. Moreover, skeleton analyse was adjusting to the tube selection. My next move is to automatise to get measurement of several images at the same time.

Concerning memory adjusting of FIJI to use TWS, I have some problem with memory and a slowdown in the process.


#8

Hi everyone,

I have a question about a curious case. When I use the CT windows (applet) in my image, I obtained one perfect ROI, but when I run the autogenerated CT macro from the same into recorded macro , the ROI is different, Why that happens or where are the error? I thinking of using this autogenerated CT macro for the other images too… Thanks so much :confused:

this is my macro:

run("RGB Color");
// Color Thresholder 2.0.0-rc-49/1.51d
// Autogenerated macro, single images only!
min=newArray(3);
max=newArray(3);
filter=newArray(3);
a=getTitle();
run("HSB Stack");
run("Convert Stack to Images");
selectWindow("Hue");
rename("0");
selectWindow("Saturation");
rename("1");
selectWindow("Brightness");
rename("2");
min[0]=0;
max[0]=147;
filter[0]="pass";
min[1]=6;
max[1]=255;
filter[1]="pass";
min[2]=0;
max[2]=255;
filter[2]="pass";
for (i=0;i<3;i++){
selectWindow(""+i);
setThreshold(min[i], max[i]);
run("Convert to Mask");
if (filter[i]=="stop") run("Invert");
}
imageCalculator("AND create", "0","1");
imageCalculator("AND create", "Result of 0","2");
for (i=0;i<3;i++){
selectWindow(""+i);
close();
}
selectWindow("Result of 0");
close();
selectWindow("Result of Result of 0");
rename(a);
// Colour Thresholding-------------
run("Find Edges");
run("Gaussian Blur...", "sigma=4 scaled");
//setOption("BlackBackground", true);
run("Make Binary");
run("Dilate");
run("Dilate");
run("Fill Holes");
run("Dilate");
run("Fill Holes");
run("Erode");
run("Erode");
run("Erode");
run("Analyze Particles...", "size=10000-Infinity pixel display include add");
//run("Skeletonize");
//run("Analyze Skeleton (2D/3D)", "prune=none prune calculate");
//selectWindow("Tagged skeleton");
//close();

This is my original image

and that is the perfect ROI when I use the same parameters of H, S and B

and that is the other ROI when I use the autogenerated CT macro with the same parameters

Finally, I’m sure that I follow the same steps from the autogenerated macro concerning Process. I thought this error was because I work with zvi files but then I converted them into RGB color with the same wrong result


#9

I personally don’t have time to dig in to this problem right now, but one option would be to slightly adjust your autogenerated macro: a couple of Dilates followed by Fill Holes and then a couple of Erodes.


#10

I come back with this subject. Now, I’m going to measure the width of the structure. How can I do this, by using skeleton or another pluging ?

Thanks for your suggestions,

Jo


#11

Do you have your image already binarized?

If so, you can get the skeleton. Measuring the thickness of each skeleton branch can be easily done using MorphoLibJ’s Geodesic Distance Map plugin (the original image being the mask and the skeleton image being the marker). Have a look at the following example:

The output image contains for each pixel/voxel the distance from the midline to the closest border.


Automated diameter measurements of a stack
MorphoLibJ's Geodesic Distance Map plugin
#12

@iarganda Your plugins are so cool. :heart_eyes: I really hope we can add MorphoLibJ stuff to Ops some day!


#13

I should work on that at some point… Hopefully soon!