Straight line with preset length macro?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

Straight line with preset length macro?

AlvinH
Hi all,

Is anyone aware of a macro or plugin that would allow me to draw a straight line with a preset length or stopping after reaching a certain length (i.e. 500 µm)?

I am aware that I can pay attention to the length measurement as I draw, but it would take too much time to measure exactly 500.00 µm each time.

Thanks
-A
Reply | Threaded
Open this post in threaded view
|

Re: Straight line with preset length macro?

Herbie
Alvin,

because you wrote "exactly 500.00 µm" ...

How do you expect this in images that are spatially discrete?

What is the spatial resolution of your images and do you consider lines
of arbitrary orientation?

Regards

Herbie

:::::::::::::::::::::::::::::::::::
Am 01.10.15 um 23:48 schrieb AlvinH:

> Hi all,
>
> Is anyone aware of a macro or plugin that would allow me to draw a
> straight line with a preset length or stopping after reaching a
> certain length (i.e. 500 µm)?
>
> I am aware that I can pay attention to the length measurement as I
> draw, but it would take too much time to measure exactly 500.00 µm
> each time.
>
> Thanks -A
>
>
>
> -- View this message in context:
> http://imagej.1557.x6.nabble.com/Straight-line-with-preset-length-macro-tp5014526.html
>
>
Sent from the ImageJ mailing list archive at Nabble.com.
>
> -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Straight line with preset length macro?

Emanuele Martini
maybe like a radius of a circle of 500um discretized?
Image Analyst @Ifom-IEO research campus -MI-
Reply | Threaded
Open this post in threaded view
|

Re: Straight line with preset length macro?

AlvinH
In reply to this post by Herbie
Thank you for the responses, Herbie and Emanuele.

I am new to ImageJ so I am not sure what "spatially discrete" images or "lines of arbitrary orientation" are. However, I'll try to describe what I have to do in more detail and maybe that'll explain what you want to know.

The image that I have to work with is 1025x684 pixels. Example image with same resolution.

Once opened, I proceed to change the units from pixels to µm (Image > Properties) as well as the Pixel Width to 2.93 (Pixel Height and Voxel Depth also changes to 2.93 automatically). The 2.93 is just to make the desired resolution roughly 3000x2000 µm (3003.25x2004.12 µm to be exact).

I found a macro provided by Wayne Rasband (Thread)

   macro "Set Length Line Tool - C00bL1de0L1ee1" {
         maxLength = 20; 
         leftClick=16
         i = 0;
         xpoints = newArray(2000);
         ypoints = newArray(2000);
         getCursorLoc(x2, y2, z, flags);
         xpoints[i]=x2; ypoints[i++]=y2;
         while (true) {
             getCursorLoc(x, y, z, flags);
             if (flags&leftClick==0) exit();
             if (x!=x2 || y!=y2) {
                xpoints[i] = x;
                ypoints[i] = y;
                i++;
                x2=x; y2=y;
                xpoints2 = Array.trim(xpoints, i);
                ypoints2 = Array.trim(ypoints, i);
                makeSelection("freeline", xpoints2, ypoints2); 
                List.setMeasurements;
                length = List.getValue("Length");
                showStatus("length="+d2s(length,2));
                if (length>=maxLength) exit;
             }
          }
    }

This macro allowed me to draw a freeline that'll stop at 20 µm. However, I want to be able draw with the straightline tool that'll stop at 500 µm. Hence, I played around and changed the code to

  macro "Set Length Line Tool - C00bL1de0L1ee1" {
         maxLength = 500; 
         leftClick=16
         i = 0;
         xpoints = newArray(1025);
         ypoints = newArray(684);
         getCursorLoc(x2, y2, z, flags);
         xpoints[i]=x2; ypoints[i++]=y2;
         while (true) {
             getCursorLoc(x, y, z, flags);
             if (flags&leftClick==0) exit();
             if (x!=x2 || y!=y2) {
                xpoints[i] = x;
                ypoints[i] = y;
                i++;
                x2=x; y2=y;
                xpoints2 = Array.trim(xpoints, i);
                ypoints2 = Array.trim(ypoints, i);
                makeLine(288, 335, x2, y2); 
                List.setMeasurements;
                length = List.getValue("Length");
                showStatus("length="+d2s(length,2));
                if (length>=maxLength) exit;
             }
          }
    }

This new macro allowed me to draw a straightline that'll stop roughly at 500 µm starting at coordinates 288,335 (just a random coordinate I chose). However, the straightline never really stops at exactly 500 µm (length measurement shows 501.30 µm).

Only after changing the Known Distance to 500 in Analyze > Set Scale (with other info being Distance in Pixels: 171. Pixel aspect ratio: 1.0, Unit of length: µm, Scale: 0.342 pixels/µm) and making the y-coordinate constant (makeLine(288, 335, x2, 335)) will I be able to draw a straight line that stops at exactly 500 µm in length. This also changes the image resolution to 2997.08x2000.00 µm (which is fine).

This macro is doable however, it becomes difficult/time consuming to do it this way when I have to repeat this process hundreds of times.

I would like to know if the macro can be tweaked to allow me to draw a straight line starting at any point on the image that can go in any direction and will stop at exactly 500 µm in length.

Sorry for the long reply. Thanks for reading/helping!
Reply | Threaded
Open this post in threaded view
|

Re: Straight line with preset length macro?

Michael Schmid
Hi Alvin,

if you want a straight line, try something like this:

macro "Fixed Length Line Tool - C00bL1de0L1ee1" {
  desiredLength = 500; //in scaled units
  leftClick=16;
  getPixelSize(unit, pixelWidth, pixelHeight);
  getCursorLoc(x0, y0, z, flags);
  while (true) {
    getCursorLoc(x, y, z, flags);
    if (flags&leftClick==0) exit();
    if (x==x0 && y==y0) {
      wait(10);
    } else {
      dx = (x - x0) * pixelWidth;
      dy = (y - y0) * pixelHeight;
      length = sqrt(dx*dx + dy*dy);  //in scaled units
      enlageFactor = desiredLength/length;
      x = x0 + (x - x0)*enlageFactor;
      y = y0 + (y - y0)*enlageFactor;
      makeLine(x0, y0, x, y);
    }
  }
}


If you want to have also lines shorter than 500, don't recalculate x, y if 'enlargeFactor' is more than 1.

Michael
________________________________________________________________
On Oct 2, 2015, at 18:21, AlvinH wrote:

> Thank you for the responses, Herbie and Emanuele.
>
> I am new to ImageJ so I am not sure what "spatially discrete" images or
> "lines of arbitrary orientation" are. However, I'll try to describe what I
> have to do in more detail and maybe that'll explain what you want to know.
>
> The image that I have to work with is *1025x684 pixels*.  Example image
> <http://4.bp.blogspot.com/-Zo65_84L9Uc/UyCmC_uw0xI/AAAAAAAACCs/oxKFQtFl0hY/s1600/red-eye-frog-hd-photography-wallpapers78.jpg>  
> with same resolution.
>
> Once opened, I proceed to change the units from *pixels to µm* (Image >
> Properties) as well as the *Pixel Width to 2.93* (Pixel Height and Voxel
> Depth also changes to 2.93 automatically). The 2.93 is just to make the
> *desired resolution roughly 3000x2000 µm* (3003.25x2004.12 µm to be exact).
>
> I found a macro provided by Wayne Rasband ( Thread
> <http://imagej.1557.x6.nabble.com/how-to-stop-the-freehand-lines-tool-at-a-set-distance-20-um-td3690197.html>
> )
>
>   macro "Set Length Line Tool - C00bL1de0L1ee1" {
>         *maxLength = 20;*
>         leftClick=16
>         i = 0;
>         xpoints = newArray(2000);
>         ypoints = newArray(2000);
>         getCursorLoc(x2, y2, z, flags);
>         xpoints[i]=x2; ypoints[i++]=y2;
>         while (true) {
>             getCursorLoc(x, y, z, flags);
>             if (flags&leftClick==0) exit();
>             if (x!=x2 || y!=y2) {
>                xpoints[i] = x;
>                ypoints[i] = y;
>                i++;
>                x2=x; y2=y;
>                xpoints2 = Array.trim(xpoints, i);
>                ypoints2 = Array.trim(ypoints, i);
>                *makeSelection("freeline", xpoints2, ypoints2);*
>                List.setMeasurements;
>                length = List.getValue("Length");
>                showStatus("length="+d2s(length,2));
>                if (length>=maxLength) exit;
>             }
>          }
>    }
>
> This macro allowed me to draw a *freeline* that'll stop at *20 µm*. However,
> I want to be able draw with the *straightline tool* that'll stop at *500
> µm*. Hence, I played around and changed the code to
>
>  macro "Set Length Line Tool - C00bL1de0L1ee1" {
> *maxLength = 500;*
>         leftClick=16
>         i = 0;
>         xpoints = newArray(1025);
>         ypoints = newArray(684);
>         getCursorLoc(x2, y2, z, flags);
>         xpoints[i]=x2; ypoints[i++]=y2;
>         while (true) {
>             getCursorLoc(x, y, z, flags);
>             if (flags&leftClick==0) exit();
>             if (x!=x2 || y!=y2) {
>                xpoints[i] = x;
>                ypoints[i] = y;
>                i++;
>                x2=x; y2=y;
>                xpoints2 = Array.trim(xpoints, i);
>                ypoints2 = Array.trim(ypoints, i);
>                *makeLine(288, 335, x2, y2);*
>                List.setMeasurements;
>                length = List.getValue("Length");
>                showStatus("length="+d2s(length,2));
>                if (length>=maxLength) exit;
>             }
>          }
>    }
>
> This new macro allowed me to draw a *straightline* that'll stop roughly at
> *500 µm* starting at coordinates 288,335 (just a random coordinate I chose).
> However, the straightline never really stops at exactly 500 µm (length
> measurement shows 501.30 µm).
>
> Only after changing the *Known Distance to 500* in *Analyze > Set Scale*
> (with other info being Distance in Pixels: 171. Pixel aspect ratio: 1.0,
> Unit of length: µm, Scale: 0.342 pixels/µm) and making the y-coordinate
> constant (*makeLine(288, 335, x2, 335)*) will I be able to draw a straight
> line that stops at exactly 500 µm in length. This also changes the image
> resolution to 2997.08x2000.00 µm (which is fine).
>
> This macro is doable however, it becomes difficult/time consuming to do it
> this way when I have to repeat this process hundreds of times.
>
> I would like to know if the macro can be tweaked to allow me to draw a
> *straight line starting at any point on the image that can go in any
> direction and will stop at exactly 500 µm in length*.
>
> Sorry for the long reply. Thanks for reading/helping!
>
>
>
>
> --
> View this message in context: http://imagej.1557.x6.nabble.com/Straight-line-with-preset-length-macro-tp5014526p5014530.html
> Sent from the ImageJ mailing list archive at Nabble.com.
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Straight line with preset length macro?

Herbie
In reply to this post by AlvinH
Alvin,

what I wrote has nothing to do with ImageJ but with logic.

If you write e.g. "*Pixel Width to 2.93*", then this is not perfectly
correct, because a pixel has no width: It is simply a number that stands
for the gray value, and numbers have no extension (width, height or the
like). What you mean is the spacing of pixels and if you understand this
(spatial discreteness), you will logically conclude that there is
nothing in between pixels and this may be the solution to understand
your problem.

HTH

Herbie

::::::::::::::::::::::::::::::::::::
Am 02.10.15 um 18:21 schrieb AlvinH:

> Thank you for the responses, Herbie and Emanuele.
>
> I am new to ImageJ so I am not sure what "spatially discrete" images or
> "lines of arbitrary orientation" are. However, I'll try to describe what I
> have to do in more detail and maybe that'll explain what you want to know.
>
> The image that I have to work with is *1025x684 pixels*.  Example image
> <http://4.bp.blogspot.com/-Zo65_84L9Uc/UyCmC_uw0xI/AAAAAAAACCs/oxKFQtFl0hY/s1600/red-eye-frog-hd-photography-wallpapers78.jpg>
> with same resolution.
>
> Once opened, I proceed to change the units from *pixels to µm* (Image >
> Properties) as well as the *Pixel Width to 2.93* (Pixel Height and Voxel
> Depth also changes to 2.93 automatically). The 2.93 is just to make the
> *desired resolution roughly 3000x2000 µm* (3003.25x2004.12 µm to be exact).
>
> I found a macro provided by Wayne Rasband ( Thread
> <http://imagej.1557.x6.nabble.com/how-to-stop-the-freehand-lines-tool-at-a-set-distance-20-um-td3690197.html>
> )
>
>     macro "Set Length Line Tool - C00bL1de0L1ee1" {
>           *maxLength = 20;*
>           leftClick=16
>           i = 0;
>           xpoints = newArray(2000);
>           ypoints = newArray(2000);
>           getCursorLoc(x2, y2, z, flags);
>           xpoints[i]=x2; ypoints[i++]=y2;
>           while (true) {
>               getCursorLoc(x, y, z, flags);
>               if (flags&leftClick==0) exit();
>               if (x!=x2 || y!=y2) {
>                  xpoints[i] = x;
>                  ypoints[i] = y;
>                  i++;
>                  x2=x; y2=y;
>                  xpoints2 = Array.trim(xpoints, i);
>                  ypoints2 = Array.trim(ypoints, i);
>                  *makeSelection("freeline", xpoints2, ypoints2);*
>                  List.setMeasurements;
>                  length = List.getValue("Length");
>                  showStatus("length="+d2s(length,2));
>                  if (length>=maxLength) exit;
>               }
>            }
>      }
>
> This macro allowed me to draw a *freeline* that'll stop at *20 µm*. However,
> I want to be able draw with the *straightline tool* that'll stop at *500
> µm*. Hence, I played around and changed the code to
>
>    macro "Set Length Line Tool - C00bL1de0L1ee1" {
> *maxLength = 500;*
>           leftClick=16
>           i = 0;
>           xpoints = newArray(1025);
>           ypoints = newArray(684);
>           getCursorLoc(x2, y2, z, flags);
>           xpoints[i]=x2; ypoints[i++]=y2;
>           while (true) {
>               getCursorLoc(x, y, z, flags);
>               if (flags&leftClick==0) exit();
>               if (x!=x2 || y!=y2) {
>                  xpoints[i] = x;
>                  ypoints[i] = y;
>                  i++;
>                  x2=x; y2=y;
>                  xpoints2 = Array.trim(xpoints, i);
>                  ypoints2 = Array.trim(ypoints, i);
>                  *makeLine(288, 335, x2, y2);*
>                  List.setMeasurements;
>                  length = List.getValue("Length");
>                  showStatus("length="+d2s(length,2));
>                  if (length>=maxLength) exit;
>               }
>            }
>      }
>
> This new macro allowed me to draw a *straightline* that'll stop roughly at
> *500 µm* starting at coordinates 288,335 (just a random coordinate I chose).
> However, the straightline never really stops at exactly 500 µm (length
> measurement shows 501.30 µm).
>
> Only after changing the *Known Distance to 500* in *Analyze > Set Scale*
> (with other info being Distance in Pixels: 171. Pixel aspect ratio: 1.0,
> Unit of length: µm, Scale: 0.342 pixels/µm) and making the y-coordinate
> constant (*makeLine(288, 335, x2, 335)*) will I be able to draw a straight
> line that stops at exactly 500 µm in length. This also changes the image
> resolution to 2997.08x2000.00 µm (which is fine).
>
> This macro is doable however, it becomes difficult/time consuming to do it
> this way when I have to repeat this process hundreds of times.
>
> I would like to know if the macro can be tweaked to allow me to draw a
> *straight line starting at any point on the image that can go in any
> direction and will stop at exactly 500 µm in length*.
>
> Sorry for the long reply. Thanks for reading/helping!
>
>
>
>
> --
> View this message in context: http://imagej.1557.x6.nabble.com/Straight-line-with-preset-length-macro-tp5014526p5014530.html
> Sent from the ImageJ mailing list archive at Nabble.com.
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Straight line with preset length macro?

AlvinH
In reply to this post by Michael Schmid
Thank you Michael!

That did the trick. I can draw anywhere on the image towards any direction and it's always 500 um in length.

On another note, do you mind clarifying "don't recalculate x, y if 'enlargeFactor' is more than 1". What would I do for that? Do I delete certain part of the macro? I have little knowledge in coding.

Thanks again.
Reply | Threaded
Open this post in threaded view
|

Re: Straight line with preset length macro?

Michael Schmid
Hi Alvin and everyone,

Wayne has improved the macro and I have added a few more bells & whistles.
Now one can also have a line where only the maximum length is fixed or a
centered line (see the options dialog).

Beware of possible additional line breaks introduced by the mailer.

Michael
__________________________________________________________________________

// Fixed Length Line Tool
// This ImageJ tool macro allows for drawing a line with a given
// fixed length or maximum length.
// One can also draw a line centered at the point where the
// mouse button was pressed.
// Hold the shift key to constrain the direction.
//
// Authors: Wayne Rasband & Michael Schmid, 2015-Oct-04

var desiredLength = 500; //in scaled units
var isMaxlength = false; //not fixed, only maximum line length
var isCentered = false;

macro "Fixed Length Line Tool - C00bL2ae4L2be5C888L083eB10Lc1f7" {
   leftClick = 16;
   shift = 1;
   getPixelSize(unit, pixelWidth, pixelHeight);
   getCursorLoc(x0, y0, z, flags);
   lastX = x0;
   lastY = y0;
   while (true) {
      getCursorLoc(x, y, z, flags);
      if (flags&leftClick == 0) exit();
      if (x==lastX && y==lastY)    //no change, don't update live profile
etc.
         wait(10);
      else {
         lastX = x;
         lastY = y;
         dx = (x - x0);
         dy = (y - y0);
         if (flags&shift != 0) {
            angle = atan2(y - y0, x - x0);
            angle = PI/4*round(4*angle/PI);
            len = maxOf(abs(dx), abs(dy));
            dx = len*cos(angle);
            dy = len*sin(angle);
         }
         dxs = dx * pixelWidth;    //in scaled units
         dys = dy * pixelHeight;
         length = sqrt(dxs*dxs + dys*dys);
         if (isCentered)
            length = 2*length;
         enlageFactor = desiredLength/length;
         if (isMaxlength && enlageFactor > 1)
            enlageFactor = 1;
         if (isCentered) {
            xS = x0 - dx*enlageFactor;
            yS = y0 - dy*enlageFactor;
         } else {
            xS = x0;
            yS = y0;
         }
         x = x0 + dx*enlageFactor;
         y = y0 + dy*enlageFactor;
         makeLine(xS, yS, x, y);
      }
   }
}

macro "Fixed Length Line Tool Options" {
   getPixelSize(unit, pixelWidth, pixelHeight);
   if (unit=="pixel") unit="pixels";
   Dialog.create("Fixed Length Line Tool Options");
   Dialog.addNumber("Desired line length", desiredLength, 2, 10, unit);
   Dialog.addCheckbox("This length is maximum", isMaxlength);
   Dialog.addCheckbox("Centered", isCentered);
   Dialog.addMessage("Hold <shift> key to constrain directions");
   Dialog.show();
   desiredLength = Dialog.getNumber();
   isMaxlength = Dialog.getCheckbox();
   isCentered = Dialog.getCheckbox();
}


__________________________________________________________________________

On Fri, October 2, 2015 19:24, AlvinH wrote:

> Thank you Michael!
>
> That did the trick. I can draw anywhere on the image towards any direction
> and it's always 500 um in length.
>
> On another note, do you mind clarifying "*don't recalculate x, y if
> 'enlargeFactor' is more than 1*". What would I do for that? Do I delete
> certain part of the macro? I have little knowledge in coding.
>
> Thanks again.
>
>
>
>
> --
> View this message in context:
> http://imagej.1557.x6.nabble.com/Straight-line-with-preset-length-macro-tp5014526p5014533.html
> Sent from the ImageJ mailing list archive at Nabble.com.
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Straight line with preset length macro?

AlvinH
You guys are amazing!
Reply | Threaded
Open this post in threaded view
|

Re: Straight line with preset length macro?

maura
In reply to this post by Michael Schmid
Hi Michael,
I am having trouble installing the macro.
I have it in my start-up macro but could only see the fixed line length options under macros in the first start-up, not anymore.. I also do not understand how to then use the macro? Is there a specific command I use while drawing a line?
Thank you,
Maura
Reply | Threaded
Open this post in threaded view
|

Re: Straight line with preset length macro?

maura
In reply to this post by Michael Schmid
Hi Michael,
I am having trouble installing the macro.
I have it in my start-up macro but could only see the fixed line length options under macros in the first start-up, not anymore.. I also do not understand how to then use the macro? Is there a specific command I use while drawing a line?
Thank you,
Maura