Perpendicular distance between 2 lines/shortest distance between 2 lines

imagej

#1

Hi,

I want to measure the perpendicular distance between 2 parallel lines placed onto a radiographic image.

Can you advise please, on an accurate and simple way to do this. Obviously, measuring the distance freehand between the 2 lines is open to error as the line drawn between them will never be completely perpendicular.

Thank you.


Measuring distance of a point from surface of tissue
#2

Hello ConnemaraPony,

if you have the mathematicall definition of the lines, then

  • compute a perpendicular line.
  • Then compute the intersections of the perpendicular line and the parallel lines.
  • Finally compute the distance between both intersections points.

HTH

George


#3

dear @ConnemaraPony,

you can try to see this topic Cephalometric analyser
there I’ve posted a plugin that I think you can use as an outiline for your task.
You can read a way to calculate perpendicular lines and distances between lines.

Have a nice day,
Emanuele Martini


#4

Thank you George and Emanuele,

I’ve tried your solution Emanuele - but can’t quite get it to work.

Please see the picture. The two yellow dots are my starting points. I’ve placed a line joining them and then created a parallel one which cuts the blue dot. The measurements I’m then interested in are the distances indicated by the green, blue and yellow lines - drawn perpendicular to the red lines.

Any further comments would be appreciated.

Thank you.


#5

Hello ConnemaraPony,

here is a procedure that gives you the desired three length measures.

  1. Open a new macro window from “Plugins > New > Macro” and
    enter the macro text that follows at the end of this message

  2. Select the “Point”-selection tool

  3. Click on an arbitrary point of the top line

  4. Type Cmd-t (Mac) or Ctrl-t (PC)

  5. Click on another point of the top line (far away from the first point)

  6. Type Cmd-t (Mac) or Ctrl-t (PC)

  7. Click on the point at the downward end of the yellow line

  8. Type Cmd-t (Mac) or Ctrl-t (PC)

  9. Click on the point at the downward end of the blue line

  10. Type Cmd-t (Mac) or Ctrl-t (PC)

  11. Click on the point at the downward end of the green line

  12. Type Cmd-t (Mac) or Ctrl-t (PC)

  13. Bring the “Macro.txt”-window to the front and type Cmd-r (Mac) or Ctrl-r (PC)

// Begin length macro
requires("1.51i");

run( "Set Measurements...", "  redirect=None decimal=3" );
roiManager ( "multi-measure measure_all" );
wait(100);
selectWindow( "ROI Manager" );
run( "Close" );

param = newArray( 2 );
x = newArray( 5 );
y = newArray( 5 );
for ( i = 0; i<5; i++ ) {
 x[i] = getResult( "X", i );
 y[i] = getResult( "Y", i );
}
selectWindow( "Results" );
run( "Close" );

//straight line
points2line( x[0], y[0], x[1], y[1], param );
a = param[0]; b = param[1];

//length 1..3
print( "length-1 = " + d2s( length( x[2], y[2], param ), 1) );
print( "length-2 = " + d2s( length( x[3], y[3], param ), 1) );
print( "length-3 = " + d2s( length( x[4], y[4], param ), 1) );

exit();
//-----------------------------------------------------
function points2line( x_0, y_0, x_1, y_1, prm ) {
 prm[1] = ( y_0 - y_1 ) / ( x_0 - x_1 );
 prm[0] = y_0 - prm[1] * x_0;
}
function length( x_0, y_0, prm ) {
 //intersection
 x_1 = x_0 + prm[1] * ( y_0 - prm[0] ) / ( prm[1] * prm[1] + 1 );
 y_1 = prm[1] * x_1 + prm[0];
 //length
 return sqrt( pow( x_0 - x_1, 2 ) + pow( y_0 - y_1, 2 ) );
}
// End

HTH

George


How to batch measure distances between points
#6

Hi Herbie,

I have been trying to do the same thing as your code does, but with a segmented line. I want to measure the shortest distance between points and one segmented line. I did not manage to adapt your code for it.

Do you think you could help?


#7

Good day Olivier,

sorry, but I don’t understand what exactly you’d like to determine.

Please provide an image or drawing similar to the one posted above by the OP.

Regards

Herbie


#8

Thanks for your reply!
Here is a sketch. I guess I need to fit a spline to the segmented line. Then I need to find the shortest distance between the points and this line. Hope it is clearer.


#9

Well Olivier,

my above code doesn’t generalize easily for your case.
Without further constraints you will have to do an extensive computation for all segments and points and then take the shortest distance.

As you may have noticed, my code uses straight lines defined by two points (function points2line), which in your case means the end points of the segments.

I think the rest is easy and I’m sure you will manage to write a suitable macro.

Good luck

Herbie


#10

Yes, I have seen that your code uses a straight line out of the two first points. I Can’t see how to use this in my example though. Anyway, thanks for your help.


#11

Olivier,

evidently there are two ways to proceed:

  1. You don’t use a segmented line from the beginning but set the start and end points of the segments (as point selections).

  2. You extract the start and end points of the segments of the segmented line by
    getSelectionCoordinates( xpoints, ypoints );
    described here:
    https://imagej.nih.gov/ij/developer/macro/functions.html#getSelectionCoordinates

Have success

Herbie


#12

You are right. I was just trying to use the approach number 1 but can’t figure out how to modify your code so that more than one segment is defined. (sorry, not good with this)


#13

Sorry Olivier,

if you really understand my code, then re-writing it for your needs isn’t difficult. I don’t have time to do it for you.

Best

Herbie


#14

You can do this with Bio7 and the R package spatstat.

Bio7 is a IDE for ecological modeling, image analysis and statistical analysis. Beside many different tools it integrates ImageJ as an Eclipse plugin and is also a complete IDE for the statistical language R.

I created special methods to transfer ImageJ selections values to R which can be easily converted to a spatstat object (see example video below)

In your example you just have to add ROI’s to the ROI Manager and transfer them to the R workspace to measure the line point distance, here are some examples.

Here the script from the video which handles several line selections (and seperates them!):

For more information please consult the spatstat documentation:

http://spatstat.org/resources.html

Here a video how to transfer point objects to spatstat:


#15

I’ll give it a try, many thanks!


#16

Please note that you have to install some additional R packages like ‘maptools’, ‘spatstat’, etc., because there are not installed by default.

Here a simple R script to install some necessary R packages:

packagesIJWorkshop<-c("knitr","formatR","rmarkdown","sp", "maptools", "rgdal", "spatstat","raster","ggplot2")
install.packages(packagesIJWorkshop, dep=TRUE, repos="http://cran.us.r-project.org")

Here a video using the Bio7 R GUI to install R packages:

If you are on MacOSX and Linux you have to install R and Rserve. For Rserve see:

See also this workshop github site:

And my compressed spatstat tutorial:

http://bio7.org/?p=2618