Login  Register

Re: Place elliptical ROI with mouse click

Posted by aweitz on Jun 25, 2009; 6:06pm
URL: http://imagej.273.s1.nabble.com/Place-elliptical-ROI-with-mouse-click-tp3691999p3692004.html

In case anyone's interested, I made a couple updates to this tool:
1. ROIs are automatically added to the ROI manager.
2. If the user right-clicks while drawing a ROI, it cancels the current drawing.

Here's the new code:

macro 'Soma ROI Tool-C00cO11cc' {
        diameter = parseInt(call("ij.Prefs.get", "SomaRoiTool.diameter", 16));
        r = diameter / 2;
        left = 16; //left-click flag
        right = 4; //right-click flag
        getCursorLoc(x0, y0, z, flags);
        makeOval(x0-r, y0-r, 2*r, 2*r);
        prevX = -1;
        prevY = -1;
        setOption("Show All", true);
        setOption("DisablePopupMenu", true);
        showStatus("Right-click to cancel current ROI.");
        do {
                getCursorLoc(x, y, z, flags);
                if ((flags&right)>0) {
                        run("Select None");
                        setOption("DisablePopupMenu", false);
                        return;
                }
                moved = (x!=x0 || y!=y0);
                if (moved && (prevX != x || prevY != y)) {
                        prevX = x;
                        prevY = y;
                        getCursorLoc(x, y, z, flags);
                        makeOval(x0-r, y0-r, 2*(r-(x0-x)), 2*(r-(y0-y)));
                }
        } while ((flags&left)>0)
        roiManager("Add");
        roiManager("select", roiManager("count")-1);
        setOption("DisablePopupMenu", false);
}

macro "Soma ROI Tool Selected" {
        diameter = parseInt(call("ij.Prefs.get", "SomaRoiTool.diameter", 16));
        diameter = getNumber("Region Diameter (pixels):", diameter);
        call("ij.Prefs.set", "SomaRoiTool.diameter", diameter);
}



aweitz wrote
Hi Michael,

Awesome tip!  This is only my second week using ImageJ, and I didn't realize how powerful macros could be.  I was able to make a few modifications to your macro in order to get the tool to behave exactly like I wanted.  This macro can now be used to replace all that source code I modified!

Here's what I settled on for the macro:

macro 'Soma ROI Tool-C00cO11cc' {
        diameter = parseInt(call("ij.Prefs.get", "SomaRoiTool.diameter", 16));
        r = diameter / 2;
        left=16; //left-click flag
        getCursorLoc(x0, y0, z, flags);
        makeOval(x0-r, y0-r, 2*r, 2*r);
        prevX = -1;
        prevY = -1;
        setOption("Show All", true)
        do {
                getCursorLoc(x, y, z, flags);
                moved = (x!=x0 || y!=y0); //maybe 1 or 2 pixel tolerance?
                if (moved && (prevX != x || prevY != y)) {
                        prevX = x;
                        prevY = y;
                        getCursorLoc(x, y, z, flags);
                        makeOval(x0-r, y0-r, 2*(r-(x0-x)), 2*(r-(y0-y)));
                }
        } while ((flags&left)>0)
}

macro "Soma ROI Tool Selected" {
        diameter = parseInt(call("ij.Prefs.get", "SomaRoiTool.diameter", 16));
        diameter = getNumber("Region Diameter (pixels):", diameter);
        call("ij.Prefs.set", "SomaRoiTool.diameter", diameter);
}


Thanks for the help!!!

Andrew

Michael Schmid-3 wrote
Hi Andrew,

why not do it all with a macro tool?

Roughly something like this:

macro 'Soma ROI Tool-C00cO11cc' {
   r = 10;  //radius for new roi
   left=16; //left-click flag
   getCursorLoc(x0, y0, z, flags);
   do {
     getCursorLoc(x, y, z, flags);
     moved = (x!=x0 || y!=y0); //maybe 1 or 2 pixel tolerance?
     if (moved) {
       getSelectionBounds(x, y, width, height);
       // depending on where the click was, resize, drag, or do nothing
       // here you can also constrain resizing, e.g. circular, min  
size, etc.
     }
   } while ((flags&left)>0)
   if (!moved)
     makeOval(x-r, y-r, 2*r+1, 2*r+1);
   //if desired, add to the roi manager (on modification, delete the  
old one first)
}

Michael
________________________________________________________________

On 23 Jun 2009, at 22:27, aweitz wrote:

> Hi everyone,
>
> Thanks so much for all the suggestions.  Unfortunately, I was  
> looking for
> some pretty specific behavior.  I needed a fast way to place and  
> resize
> ROIs, since each one of my images has about 100 of them.  I was  
> able to
> modify some of the source code and create a plugin to give me the  
> behavior I
> desired...
>
> I ended up implementing a new class called SomaRoi that extends  
> OvalRoi:
> public class SomaRoi extends OvalRoi {
>
> protected int region_size;
>
> public SomaRoi (int x, int y, int diameter, ImagePlus imp) {
>
> super(x, y, imp);
> region_size = diameter;
> }
>
> protected void handleMouseDrag(int sx, int sy, int flags) {
>
> if (state == CONSTRUCTING)
> flags = flags|Event.CTRL_MASK;
>
> super.handleMouseDrag(sx, sy, flags);
> }
>
> public void draw(Graphics g) {
>
> if (width == 0 && height == 0) {
> width = region_size;
> height = region_size;
> x = x - width/2;
> y = y - height/2;
> startX = x;
> startY = y;
> oldWidth = width;
> oldHeight = height;
> oldX = x;
> oldY = y;
> }
> else if (state == CONSTRUCTING) {
> x = x + width/2;
> y = y + height/2;
> oldX = x;
> oldY = y;
> }
>
> state = CONSTRUCTING;
> super.draw(g);
> }
> }
>
>
>
> Then I added a function to ImagePlus that creates soma ROIs:
> public void createNewSomaRoi(int sx, int sy, int diameter) {
> killRoi();
> roi = new SomaRoi(sx, sy, diameter, this);
> }
>
>
> Finally, I created a plugin that calls createNewSomaRoi() when the  
> user
> clicks on the image:
> public class Soma_Roi_Tool implements PlugInFilter {
>
> protected static int region_size;
>
> public int setup(String arg, ImagePlus imp) {
> this.region_size = 16;
> return DOES_ALL;
> }
>
> public void run(ImageProcessor ip) {
> if (IJ.versionLessThan("1.37c")) return;
> showSomaDialog();
> String macro =
> "macro 'Soma ROI Tool-C00cO11cc' {\n" +
> "  getCursorLoc(x, y, z, flags);\n" +
> "  call('Soma_Roi_Tool.mousePressed', x, y, z, flags);\n"+
> "}";
> new MacroInstaller().install(macro);
>   }
>
> public static void mousePressed(String xs, String ys, String zs,  
> String
> flags) {
> int x = Integer.parseInt(xs);
> int y = Integer.parseInt(ys);
> ImagePlus img = WindowManager.getCurrentImage();
> if (img!=null)
> img.createNewSomaRoi(x, y, region_size);
> }
>
> public static void showSomaDialog() {
> GenericDialog gd = new GenericDialog("Soma ROI Tool");
> gd.addNumericField("Diameter:", region_size, 0, 2, "pixels");
> gd.showDialog();
> if (gd.wasCanceled()) return;
> region_size = (int)gd.getNextNumber();
> }
> }
>
>
> This gave me the exact behavior I was looking for.  The only thing  
> I'm not
> happy about is having to modify the ImagePlus class.  If anyone has  
> an idea
> for doing this without modifying ImagePlus, or if anyone can  
> suggest a more
> elegant way of implementing this, I'd be happy to listen.
>
> Thanks again!
> Andrew
>
>
>
> dpoburko wrote:
>>
>> aweitz wrote:
>>> Hi,
>>>
>>> I'd like to modify the elliptical ROI tool.  Currently, the tool  
>>> only
>>> places
>>> ROIs with click and drag (to specify ellipse size).  A click  
>>> without a
>>> drag
>>> does nothing.  Instead, I'd like the click (without a drag) to  
>>> place an
>>> ROI
>>> of set size (12x12) at the area of the mouse click.  The click  
>>> and drag
>>> behavior should remain unmodified.
>>>
>>> Can anyone tell me where I can look in the code to make this
>>> modification?
>>>
>>> Thanks!
>>> Andrew
>>>
>> You could try the Time Series Analyzer plugin. (
>> http://rsb.info.nih.gov/ij/plugins/time-series.html) It will  
>> provide a
>> GUI to let you select a give ROI size then create ROIs with a single
>> click. You can resize ROIs by selecting a given ROI and dragging  
>> to the
>> new size or position, then clicking on Update in the ROI manager.
>>
>> Hope that helps,
>> Damon
>>
>> --
>>
>> Damon Poburko, PhD
>> Postdoctoral Research Fellow
>> Stanford University School of Medicine
>> Dept. of Molecular & Cellular Physiology
>> 279 Campus Dr., Beckman B103, Stanford, CA 94305
>> Ph: 650 725 7564, fax: 650 725 8021
>>
>>
>
> --
> View this message in context: http://n2.nabble.com/Place-elliptical- 
> ROI-with-mouse-click-tp3139919p3144862.html
> Sent from the ImageJ mailing list archive at Nabble.com.