# Average distance between two lines and between a line and particles

Hi
@Catalina
My macro is designed for this image.
It deals with the first question.
It measures thickness.

Greetings

1 Like

Well, my first suggestion (if you follow the link) can be applied to both measurements by creating a binary from the lower line to the bottom and then apply the “Exact Distance Euclidean” function which gives you distances from the binary as pixel values.

Now you can select the upper line and extract the distances under the lines (see snippet in the post).

Vice versa you can create a binary form the upper line to the top and then extract the pixel values at the different point selections

1 Like

Hi @Mathew it works fine to measure the distance between then lines and the results are very reliable, however the distance is not perpendicular to the upper line, and then that does not give me the “real” thickness.

I’m gonna try this,

thank you!!!

Hi @eljonco,

thank you for your answer and the approach, I didn’t know this function and that could be very usefull in some cases, however for this particular analysis is not perfect because the width is not constant.

Greetings!

Please note that you can make your line and point selections in the original image and add them to the ROI Manager.
Then you can create a simple binary image with the same dimension (and if necessary scale) and enable the selections on the new image to easier create the binary to apply the measurements.

1 Like

Here a screenshot what it approx. should look like for the 1 question:

Here the binary with the lower line filled to the bottom (of cours it should be more precise - see my link):

And then the Euclidean distance image (Exact Euclidean Distance Transfom) from this binary on which you can enable the ROI’s (point and lines) to extract the pixel values at the coordinates (distances):

You can also create a binary from the upper line filled to the top to measure the distance of the points to the upper ROI.

I would also measure some controls manually if everything was setup correctly.

1 Like

Hi,

thank you so much for your response. I am not obtaining the same as you when I try to get the binary just by drawing a segmented line.

Could you explain me a bit more in detail how to do that?

Hi. I was wondering, can you get the area of the shape (area between the upper and lower line). It seems like you draw a closed shape with vertical lines at the edges of the image. If so, you could simply divide the area with the width of the image and get a mean distance (height). Would that work?

Hi Sorel,

yes, I am getting the area of that shape actually for a further analysis I have to do. However the width is varying along the length of the layer (in some images is very different) and it is not a regular shape as well, therefore it is not that simple (that was also my first way to try to do it).

I see, It would have been to easy. Good luck.

Hi
As @Bio7 had suggested, there is a macro below that gives you a map of Euclidean distances.
Obviously, we can still improve and especially extract a table of distances (Not performed here).
Greetings.
Mathew

macro "Average distance between two lines and between a line and particles. "
{
requires("1.52v");
setBackgroundColor(0,0,0);
setOption("BlackBackground",true);
// Clean the environment
//-----------------------------------
msg="Have you cleaned up the environment?";
yesLabel="Yes";
noLabel="No";
getBoolean(msg, yesLabel, noLabel);
//---------------------------
// Start batch mode
setBatchMode(true);
//-----------------------------
// Copy and select
orig=getImageID();
run("Duplicate...","copy1");
close("\\Others");
copy1=getImageID();
selectImage(copy1);
run("Duplicate...","copy2");
//-------------------------------
// Start processing
//-------------------------------
run("Duplicate...", "title=1");
run("Duplicate...", "title=2");
run("RGB to CMYK");
run("Stack to Images");
close("C"); close("Y");
close("ROI Manager");
//-----------------------------------------
// Step 1: Delete the upper part.
selectWindow("M");
setAutoThreshold("Triangle dark");
//run("Threshold...");
run("Fill Holes");
wait(1000);
roiManager("Select", 0);
selectWindow("1");
run("Restore Selection");
run("Clear", "slice");
run("Select None");
roiManager("reset");
close("Results");
close("M");
//----------------------------------
// Step 2: Delete the lower part.
selectWindow("K");
setAutoThreshold("Triangle dark");
//run("Threshold...");
roiManager("Select", 0);
selectWindow("1");
run("Restore Selection");
run("Clear", "slice");
run("Select None");
close("K");
//----------------------------------------------------
// Step 3: Isolate the part to be studied.
selectWindow("1");
//setTool("wand");
doWand(52, 1496, 51, "Legacy");
setBackgroundColor(0, 0, 0);
run("Clear Outside");
run("Select None");
run("Duplicate...", " ");
doWand(52, 1496, 51, "Legacy");
setBackgroundColor(255, 255, 255);
doWand(52, 1496, 51, "Legacy");
run("Clear");
run("Select None");
roiManager("reset");
//--------------------------------------------
//Step 4: Select all points of interest
selectWindow("1");
run("Split Channels");
close("1 (blue)");
close("1 (green)");
selectWindow("1 (red)");
run("Find Maxima...", "prominence=50 output=List");
//----------------------------------------------------
// Step 5: Create the Euclidean distance map
selectWindow("1-1");
setOption("BlackBackground", true);
run("Distance Map");
run("16 Colors");
//-------------------------
// Step 6: Place all points of interest on the Euclidean distance map
for(i=0;i<nResults;i++)
{
x=getResult("X",i);
print(x);
y=getResult("Y",i);
print(y);
selectWindow("1-1");
makePoint(x,y);
}
roiManager("Show All without labels");
//-------------------------------
// End of processing
//----------------------------
// End of batch mode
setBatchMode(false);
run("Calibration Bar...", "location=[Upper Right] fill=White label=Black number=5 decimal=0 font=12 zoom=4 overlay");
close("Log")
//--------------------------------
exit("All is done !");
}

1 Like

Another presentation:
Macro:

macro  "Average distance a line and particles. (2) "
{
requires("1.52v");
setBackgroundColor(0,0,0);
setOption("BlackBackground",true);
//---------------------------
// Start batch mode
//Copy and select
//--------------------------
id=getImageID();
selectImage(id);
run("Duplicate...","title=1");
close("\\Others");
setBatchMode(true);
run("Duplicate...","title=2");
run("Duplicate...","title=3");
//-------------------------------
// Start processing
//-------------------------------
run("Invert");
run("RGB to CMYK");
run("Stack to Images");
//-----------------------------------------------
// Clean the lower part
//-----------------------------------------------
selectWindow("C"); close("K"); close("Y"); close("M");
close("3");
setAutoThreshold("Huang dark");
//run("Threshold...");
setOption("BlackBackground", true);
run("Fill Holes");
run("Set Measurements...", "area add redirect=None decimal=4");
setBackgroundColor(0, 0, 0);
roiManager("Select", 0);
run("Clear Outside");
//---------------------------------------------
roiManager("Show All without labels");
roiManager("Show None");
roiManager("Delete");
run("Duplicate...", " ");
//---------------------------------------------
//  Clean the upper part and create the distance map
//---------------------------------------------
setAutoThreshold("RenyiEntropy ");
//run("Threshold...");
//setThreshold(0, 0);
setOption("BlackBackground", true);
//-----------------------------------------------
roiManager("Select", 0);
run("Clear Outside");
roiManager("Show All without labels");
roiManager("Show None");
roiManager("Delete");
//-----------------------------------------------
run("Distance Map");
run("16 Colors");
close("C");
//----------------------------------------------
// Select particles
//-----------------------------------------------
selectWindow("2");
run("Split Channels");
close("2 (green)");close("2 (blue)");
setAutoThreshold("Yen dark");
//run("Threshold...");
//setThreshold(76, 255);
setOption("BlackBackground", true);
run("Watershed");
run("Set Measurements...", "area add redirect=None decimal=4");
selectWindow("1");
roiManager("Show All without labels");
selectWindow("C-1");
run("Calibration Bar...", "location=[Upper Right] fill=White label=Black number=5 decimal=0 font=12 zoom=4 overlay");
close("2 (red)");
//------------------------------------------------
// Transfer the particles to the distance map.
//-------------------------------------------------
run("From ROI Manager");
run("Tile");
//-----------------------------
// End of processing
//----------------------------
// End of batch mode
setBatchMode(false);
run("Tile");
//--------------------------------
exit("All is done !");
}

1 Like

Dear Mathew, that looks very well, let me check the macro and the results and I let you know how it is. Thank you very much for your time and effort.

Hi Mathew,

I’m still working with your macro trying to understand it. Although I can’t make it work in my program. I wanted to know which version are you using, because it does not recognize the comand CMYG. Is there an alternative to this?
I also have troubles to run the 16 colors for the distance map, how can I do this?

Thank you!

1 Like

I work with ImageJ (and not FIJI).

requires("1.52v");

You need the plug-in:
https://imagej.nih.gov/ij/plugins/cmyk/index.html

From the binary image you have to do:

run("Distance Map");
run("16 Colors")

Image —> Look Up Table -----> 16 Colors

Good luck

1 Like

Thank you again @Mathew. With the plugin works perfectly well.

@Catalina

Hi
@Catalina
If you want information on loops then read this:
https://imagej.nih.gov/ij/developer/macro/macros.html
As for the rest, you need to browse the different themes of the forum.
It is a “treasure” of information.
Have you ever been here?
https://imagej.nih.gov/ij/
Otherwise you have a lot of online courses:( The latest on Youtube)
NEUBIAS
haesleinhuepf
I forget a lot (Sorry).