Finding the centerline between two other lines in a 2D image

imagej
segmentation

#1

Hello,

I am trying to take some measurements within a 2D image. The first step is to trace a structure by simply drawing a line on both sides (yellow dotted lines). Then halfway between those lines I would like to calculate and draw the centerline (red line). Ideally I could then calculate the radius at several points along the centerline (transverse red lines).

Picture1

I have tried the skeletonize plugin but I have not had much success.

Any advice would be greatly appreciated, thank you!

  • Alex

#2

Hi @alghobbes,

A combination of skeletonisation and distance mapping should work reasonably well.

Instead of just drawing two lines as you have done, enclose a region, from which you can then create a mask.

You can then create both a distance map and skeleton from that mask, which should give you the information you require.

D.


#3

Thanks djpbarry!

I’ve been attempting what you have suggested and can’t get any farther.

I enclosed the entire region (from “AVC” to “AI” and the yellow lines).

I attempted to create a mask, however I just ended up with white lines on a black background. I then decided to fill and then had a white blob, as below (is this what you mean?)

Blob|nullxnull

Then I attempted to skeletonize using Skeltonize3D. I tried to select the lines corresponding to AVC and AI in the ROI manager so that the thinning algorithm would start pruning from the top and bottom (yellow lines). However, this did not work and I ended up with something like this. Is it because you can only select one ROI to exclude from pruning? I couln’t get the ImageJ legacy skeletonize to do anything.

Blob_skeleton|nullxnull

Thanks for your help! I am in the process of writing a MatLab code that uses iterations of the Hough transform to do this along a segmented curved line but I’d like to get something done more quickly.


#4

Good day,

below please find an ImageJ-macro that may help with your problem. It is partly based on the suggestion of Dave Barry.

It requires that you have drawn a closed curve as an overlay on your image like in the following example image in the ZIP-archive:
Original.tif.zip (219.6 KB)
Unzip the archive, then open the image “Original.tif” in ImageJ. The closed curve is drawn in green.

Macro-code:

setBatchMode(true);
orig = getImageID();
run("To ROI Manager");
newImage("Inter", "8-bit black", getWidth(), getHeight(), 1);
roiManager("Select", 0);
setBackgroundColor(255, 255, 255);
run("Clear", "slice");
run("Select None");
setOption("BlackBackground", true);
run("Make Binary");
run("Skeletonize");
run("Create Selection");
selectImage(orig);
run("Restore Selection");
roiManager("Add");
roiManager("Select", 1);
roiManager("Set Color", "blue");
roiManager("Set Line Width", 2);
run("From ROI Manager");
run("Overlay Options...", "stroke=none width=0 fill=none");
setBatchMode(false);
exit();

Paste the above macro code to an empty macro window (Plugins >> New >> Macro) and, with the above example image opened in ImageJ, run it.

Regards

Herbie


#5

Herbie,

Thank you so much for the macro, It has helped me to understand the process.

One problem I am having though is that I need only the outer two lines (dotted yellow) to create the centerline. That is, I don’t want the lines that enclose the shape to influence the centerline calculation. From the science perspective, this image is of the atrium of an embryonic heart (fish). I want to create a centerline down the center of the atrium and use it to take various measurements.

Thanks again, either way your macro will be useful for me!


#6

One problem I am having though is that I need only the outer two lines (dotted yellow) to create the centerline.

Yes of course, this is what you want but as Dave Barry suggested

Instead of just drawing two lines as you have done, enclose a region, from which you can then create a mask.

and because I refer explicitely to his suggestion, I presently see no simple way of doing it the way you wish.

It’s your turn now!

Regards

Herbie


#7

Given an image with both lines as spline and overlay
FishHeart.zip (219.3 KB)
I get
FishHeart
with the following ImageJ-macro:

// imagej-macro "centerLine" (Herbie G., 17. September 2018)
// requires an image with two lines as spline overlay
requires( "1.52f" );
setBatchMode(true);
run("To ROI Manager");
roiManager("Show All without labels");
roiManager("select", 0);
Roi.getSplineAnchors(x1, y1);
roiManager("select", 1);
Roi.getSplineAnchors(x2, y2);
if (x1.length>x2.length) {
   Roi.setPolylineSplineAnchors(Array.resample(x2,x1.length),Array.resample(y2,x1.length));
   roiManager("add");
   roiManager("select", 1);
} else {
   Roi.setPolylineSplineAnchors(Array.resample(x1,x2.length),Array.resample(y1,x2.length));
   roiManager("add");
   roiManager("select", 0);
}
roiManager("Delete");
roiManager("select", 1);
Roi.getSplineAnchors(x2, y2);
for ( i=0; i<x2.length; i++ ) { 
   x1[i] = (x1[i]+x2[i])*0.5;
   y1[i] = (y1[i]+y2[i])*0.5;
}
Roi.setPolylineSplineAnchors(x1,y1);
roiManager("add");
run("From ROI Manager");
setBatchMode(false);
exit();
// imagej-macro "centerLine" (Herbie G., 17. September 2018)

Unzip the ZIP-archive with the sample image and open the latter in imageJ.
Then paste the above macro code to an empty macro window (Plugins >> New >> Macro) and run it.

HTH

Herbie

PS:
Result with shorter lines and transverse lines at 1/3 and 2/3 of the line length:
FishHeart-A