Rotating multiple recangular selections in a row (which are orientated to a pre-drawn line selection) along the line

Hello,

my problem is the following and I would be glad to get some help.

My aim is to get 5 ROIs that are orientated to a pre-drawn line along an MRI of intervertebral disc (IVD).

  1. My first tries of writing a macro for this started with the instruction to writing a line with the fictional coordinates x1,y1,x2,y2.
linestartx = 100;
linestarty = 400;
lineendx = 600;
lineendy = 200;
makeLine(linestartx, linestarty, lineendx, lineendy);
roiManager("Add");

Actually, I want the macro to make use of 2 lines that I drew by hand before, to set both width and height of the 5 ROIs I tried getLine(x1,y1,x2,y2); but it only works for one but not two selections. If I use getLine[Name of ROI in ROI-Manager](x1,y1,x2,y2); it doesn’t work.
After this I renamed both selections to “n” and “m” and tried to use getLinen(x1,y1,x2,y2); and getLinem(x1,y1,x2,y2); but I only got “undefined identifier” so it doesn’t work either.
Does anybody know why it doesn’t work? This is my first time doing script writing so it might be a small problem that I just don’t understand with my non-professional knowledge.
How do I have to change the command so that it targets the first and second line-ROI, but not only the first?

Here is an exerpt of my script:

getLine(x1, y1, x2, y2, lineWidth);

linestartx = x1;
linestarty = y1;
lineendx = x2;
lineendy = y2;

linelengthx = lineendx - linestartx;
linelengthy = lineendy - linestarty;
linelength1 = sqrt(linelengthx*linelengthx + linelengthy*linelengthy)

tileWidth = (linelengthx / n) - 1;

getLine0424-0313(x3, y3, x4, y4, lineWidth);

linestartx = x3;
linestarty = y3;
lineendx = x4;
lineendy = y4;

linelengthx = lineendx - linestartx;
linelengthy = lineendy - linestarty;
linelength2 = sqrt(linelengthx*linelengthx + linelengthy*linelengthy)


tileHeight = linelenght2;

sample picture of the two line selections perpendicular to each other, one measuring height and one length of the IVD.

  1. Myactual approach was this:
    Since the IVD is not exactly horizontal I tried to first draw a line along the IVD, then drew 5 ROIs along the line via this Macro:
n = getNumber("How many divisions (e.g., 2 means quarters)?", 2); 
id = getImageID(); 
title = getTitle(); 
getLocationAndSize(locX, locY, sizeW, sizeH); 
width = getWidth(); 
height = getHeight(); 

getLine(x1, y1, x2, y2, lineWidth);

linestartx = x1;
linestarty = y1;
lineendx = x2;
lineendy = y2;

linelengthx = lineendx - linestartx;
linelengthy = lineendy - linestarty;
linelength = sqrt(linelengthx*linelengthx + linelengthy*linelengthy)

tileWidth = (linelengthx / n) - 1;
tileHeight = 10;

c = linelength / n;
a = linelengthx / n;
b = sqrt(c*c - a*a);

for (x = 0; x < n; x++) { 
	offsetX = linestartx + x * (tileWidth + 1);
	offsetY = linestarty - x*b - tileHeight / 2; 
	makeRectangle(offsetX, offsetY, tileWidth, tileHeight);
	roiManager("Add");

}

The Thing now is that the ROIs follow the line, but aren’t rotatet in the line angle yet. They’re only drawn horizontally.I want top and bottom lines of the rectangular selection to be parallel to the line selection.
Is there a possible way to write some more commands to rotate the ROIs around the angle of the line selection?
I can only think about really compilcate ways using sin(alpha) and/or Pythagoras theorem… but I don’t know how to exactly write it down. I’m sorry :frowning:

My last idea is this:
I want to rotate the picture so that the IVD is exactly horizontal (angle=0) and horizontal ROIs can be drawn on it.
I get the angle of the intervertebral disc via drawing a line over the width of the IVD --> line tool --> add to ROI-Manager [t] --> Measure --> angle. Rotating the picture around that angle works via --> Image --> Transform --> Rotate --> angle (degress) --> OK

This is what I get by recording the execution:

run("Rotate... ", "angle=14.9 grid=1 interpolation=Bilinear");

Now I tried to adjust the execution, so that it would first measure the angle of the line and then use it for rotating (by setting angle = lineAngle):

getLine(x1, y1, x2, y2, lineAngle);
run("Rotate... ", "angle=lineAngle grid=1 interpolation=Bilinear");

The sad thing now is though, that it sometimes works and sometimes it either only rotates around a smaller angle (whereever this is coming from) or it doesnt rotate the picture at all.

The macro I used to draw 5 ROIs horizontally (combined with the one above for rotating the image):

n = getNumber("How many divisions (e.g., 2 means quarters)?", 2); 
id = getImageID(); 
title = getTitle(); 
getLocationAndSize(locX, locY, sizeW, sizeH); 
width = getWidth(); 
height = getHeight(); 

getLine(x1, y1, x2, y2, lineWidth);

linestartx = x1;
linestarty = y1;
lineendx = x2;
lineendy = y2;

linelengthx = lineendx - linestartx;
linelengthy = lineendy - linestarty;
linelength = sqrt(linelengthx*linelengthx + linelengthy*linelengthy)

tileWidth = (linelengthx / n) - 1;
tileHeight = 10;

c = linelength / n;
a = linelengthx / n;
b = sqrt(c*c - a*a);

for (x = 0; x < n; x++) { 
	offsetX = linestartx + x * (tileWidth + 1); 
	offsetY = linestarty - tileHeight/2; 
	makeRectangle(offsetX, offsetY, tileWidth, tileHeight);
	roiManager("Add");

}

If you can make my first and second attempt work I would be really happy because I guess they are making the whole proces easier than my last idea…

But I am thankful for any kind of help or any approach to make it work!
Yours, Phoebe

Okay somehow my sample pictures didn’t get uploaded. I will try again…

Posting images in this forum in my experience is not straight forward. If you try to post an image illustrating ist and soll, you can use .jpg images all right. For quantitative measurements, post 8-bit tiff or png.

That’s because the command is getLine() and ImageJ interprets your getLinem as a variable (identifier).

You will want to have one line selection active at a time; if you want the routine to use 2 lines as input parameters, make them 2 separate ROIs in the ROI manager and handle them consecutively after you select either using
roiManager("select", i);

(If you want the resulting lines/rectangles as extra ROIs in the ROI manager, it is handy to keep track of the ‘top of the stack’ of the ROIs you use as input.)

Do you want the 5 line ROIs parallel or perpendicular to the two line ROIs you drew?
When parallel, I guess you want the three lines to have their endpoints regularly spaced, lined up with the endpoints of your two input lines, so you get four areas; | i i i |, where ‘|’ is a line you drew, ‘i’ is a line in between and the spaces are the tiles you want to measure? Or is it that each of the five lines has a different rotation and the ‘rectangles’ are actually not rectangles but polygons narrower on one side? In that case, each polygon can get opposite edge coordinates calculated from the distance/5 between the endpoints of the respective input lines.

If you want a rectangular selection rotated (ie. not the image rotated but the selection), you need to make it a polygon with the coordinates being the result of the appropriate trigoniometric calculations. As an illustration to this, start the macro recorder, make a rectangle selection, choose Selection Rotator from the >> menu bar, rotate the rectangle. You will see the makePoligon() command appear in the Recorder window, not some magic ‘rotateRectangleSelectionCoordinates(angle)’ command (as that doesn’t exist).

As far as trigoniometry goes, create your rectangle coordinates, calculate the rectangle’s center, translate the rectangle center to (0,0), perform the rotation you want and translate the rectangle’s center back to where you got it from.