File: SpecifyROI.java

package info (click to toggle)
imagej 1.46a-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 4,248 kB
  • sloc: java: 89,778; sh: 311; xml: 51; makefile: 6
file content (176 lines) | stat: -rw-r--r-- 5,570 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
package ij.plugin;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import ij.*;
import ij.gui.*;
import ij.process.*;
import ij.util.Tools;
import ij.measure.Calibration;

/**
 *      This plugin implements the Edit/Selection/Specify command.<p>

 *      New update, correctly handling existing oval ROIs, the case that 
 *      "Centered" is already selected when the plugin starts, and always 
 *      restoring the original ROI when the dialog is cancelled (JW, 2008/02/22)
 *
 *      Enhancing the original plugin created by Jeffrey Kuhn, this one takes,
 *      in addition to width and height and the option to have an oval ROI from 
 *      the original program, x & y coordinates, slice number, and the option to have
 *      the x & y coordinates centered or in default top left corner of ROI.
 *      The original creator is Jeffrey Kuhn, The University of Texas at Austin,
 *	    jkuhn@ccwf.cc.utexas.edu
 *
 *      @author Joachim Wesner
 *      @author Leica Microsystems CMS GmbH
 *      @author joachim.wesner@leica-microsystems.com
 *
 *      @author Anthony Padua
 *      @author Duke University Medical Center, Department of Radiology
 *      @author padua001@mc.duke.edu
 *      
 */
public class SpecifyROI implements PlugIn, DialogListener {
    static double xRoi, yRoi, width, height;
    static boolean  oval;
    static boolean  centered;
    static boolean scaledUnits;
    static Rectangle prevRoi;
    static double prevPixelWidth = 1.0;
    int iSlice;
    boolean bAbort;
    ImagePlus imp;
    Vector fields, checkboxes;
    int stackSize;

	public void run(String arg) {
		imp = IJ.getImage();
		stackSize = imp!=null?imp.getStackSize():0;
		Roi roi = imp.getRoi();
		Calibration cal = imp.getCalibration();
		if (roi!=null && roi.getBounds().equals(prevRoi) && cal.pixelWidth==prevPixelWidth)
			roi = null;
		if (roi!=null) {
    		boolean rectOrOval = roi!=null && (roi.getType()==Roi.RECTANGLE||roi.getType()==Roi.OVAL);
    		oval = rectOrOval && (roi.getType()==Roi.OVAL);	// Handle existing oval ROI
			Rectangle r = roi.getBounds();
			width = r.width;
			height = r.height;
			xRoi = r.x;
			yRoi = r.y;
			if (scaledUnits && cal.scaled()) {
				xRoi = xRoi*cal.pixelWidth;
				yRoi = yRoi*cal.pixelHeight;
				width = width*cal.pixelWidth;
				height = height*cal.pixelHeight;
			}
    	} else if (!validDialogValues()) {
			width = imp.getWidth()/2;
			height = imp.getHeight()/2;
			xRoi = width/2;
			yRoi = height/2; 
		}
		if (centered) {	// Make xRoi and yRoi consistent when centered mode is active
			xRoi += width/2.0;
			yRoi += height/2.0; 
		}
		iSlice = imp.getCurrentSlice();
		showDialog();
	}
	
	boolean validDialogValues() {
		Calibration cal = imp.getCalibration();
		double pw=cal.pixelWidth, ph=cal.pixelHeight;
		if (width/pw<1.5 || height/ph<1.5)
			return false;
		if (xRoi/pw>=imp.getWidth() || yRoi/ph>=imp.getHeight())
			return false;
		return true;
	}

    /**
     *	Creates a dialog box, allowing the user to enter the requested
     *	width, height, x & y coordinates, slice number for a Region Of Interest,
     *  option for oval, and option for whether x & y coordinates to be centered.
     */
    void showDialog() {
    	Calibration cal = imp.getCalibration();
    	int digits = 0;
    	if (scaledUnits && cal.scaled())
    		digits = 2;
    	Roi roi = imp.getRoi();
    	if (roi==null)
    		drawRoi();
        GenericDialog gd = new GenericDialog("Specify");
        gd.addNumericField("Width:", width, digits);
        gd.addNumericField("Height:", height, digits);
        gd.addNumericField("X Coordinate:", xRoi, digits);
        gd.addNumericField("Y Coordinate:", yRoi, digits);
        if (stackSize>1)
        	gd.addNumericField("Slice:", iSlice, 0);
        gd.addCheckbox("Oval", oval);
        gd.addCheckbox("Centered",centered);
        if (cal.scaled())
            gd.addCheckbox("Scaled Units ("+cal.getUnits()+")", scaledUnits);
        fields = gd.getNumericFields();
        gd.addDialogListener(this);
        gd.showDialog();
        if (gd.wasCanceled()) {
        	 if (roi==null)
        		imp.killRoi();
        	 else // *ALWAYS* restore initial ROI when cancelled
        		imp.setRoi(roi);
        }
    }
    
	void drawRoi() {
		int iX = (int)xRoi;
		int iY = (int)yRoi;
		if (centered) {
			iX = (int)(xRoi - (width/2));
			iY = (int)(yRoi - (height/2));
		}
		int iWidth = (int)width;
		int iHeight = (int)height;
		Calibration cal = imp.getCalibration();
		if (scaledUnits && cal.scaled()) {
			iX = (int)Math.round(iX/cal.pixelWidth);
			iY = (int)Math.round(iY/cal.pixelHeight);
			iWidth = (int)Math.round(width/cal.pixelWidth);
			iHeight = (int)Math.round(height/cal.pixelHeight);
			prevPixelWidth = cal.pixelWidth;
		}
		Roi roi;
		if (oval)
			roi = new OvalRoi(iX, iY, iWidth, iHeight, imp);
		else
			roi = new Roi(iX, iY, iWidth, iHeight);
		imp.setRoi(roi);
		prevRoi = roi.getBounds();
		prevPixelWidth = cal.pixelWidth;
	}
    	
	public boolean dialogItemChanged(GenericDialog gd, AWTEvent e) {
		if (IJ.isMacOSX()) IJ.wait(100);
		width = gd.getNextNumber();
		height = gd.getNextNumber();
		xRoi = gd.getNextNumber();	
		yRoi = gd.getNextNumber();
		if (stackSize>1)	
			iSlice = (int) gd.getNextNumber(); 
		oval = gd.getNextBoolean();
		centered = gd.getNextBoolean();
		if (imp.getCalibration().scaled())
			scaledUnits = gd.getNextBoolean();
		if (gd.invalidNumber())
			return false;
		else {
			if (stackSize>1 && iSlice>0 && iSlice<=stackSize)
			    imp.setSlice(iSlice);
			drawRoi();
			return true;
		}
    }

}