5 import ij.measure.Calibration;
12 float[] kernel = {1f, 1f, 1f, 1f, 1f};
13 float[] kernel3 = {1f, 1f, 1f};
16 public void run(String arg) {
20 if (arg.equals(
"all"))
21 imp.
setRoi(0,0,imp.getWidth(),imp.getHeight());
22 else if (arg.equals(
"none"))
24 else if (arg.equals(
"restore"))
26 else if (arg.equals(
"spline"))
28 else if (arg.equals(
"ellipse"))
30 else if (arg.equals(
"hull"))
32 else if (arg.equals(
"mask"))
34 else if (arg.equals(
"inverse"))
39 Roi roi = imp.getRoi();
42 int type = roi.getType();
43 boolean segmentedSelection = type==Roi.POLYGON||type==Roi.POLYLINE;
44 if (!(segmentedSelection||type==Roi.FREEROI||type==Roi.TRACED_ROI||type==Roi.FREELINE))
45 {
IJ.
showMessage(
"Spline",
"Polygon or polyline selection required");
return;}
46 PolygonRoi p = (PolygonRoi)roi;
47 double length = getLength(p);
48 if (!segmentedSelection)
49 p = trimPolygon(p, length);
50 int evaluationPoints = (int)(length/2.0);
51 double mag = imp.getCanvas().getMagnification();
53 evaluationPoints *= mag;;
54 if (evaluationPoints<100)
55 evaluationPoints = 100;
56 p.fitSpline(evaluationPoints);
60 double getLength(PolygonRoi roi) {
62 double spw=cal.pixelWidth, sph=cal.pixelHeight;
63 cal.pixelWidth=1.0; cal.pixelHeight=1.0;
64 double length = roi.getLength();
65 cal.pixelWidth=spw; cal.pixelHeight=sph;
69 PolygonRoi trimPolygon(PolygonRoi roi,
double length) {
70 int[] x = roi.getXCoordinates();
71 int[] y = roi.getYCoordinates();
72 int n = roi.getNCoordinates();
73 float[] curvature = getCurvature(x, y, n);
74 Rectangle r = roi.getBounds();
75 double threshold = rodbard(length);
77 double distance = Math.sqrt((x[1]-x[0])*(x[1]-x[0])+(y[1]-y[0])*(y[1]-y[0]));
78 x[0] += r.x; y[0]+=r.y;
81 for (
int i=1; i<n-1; i++) {
82 x1=x[i]; y1=y[i]; x2=x[i+1]; y2=y[i+1];
83 distance += Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)) + 1;
84 distance += curvature[i]*2;
85 if (distance>=threshold) {
92 int type = roi.getType()==Roi.FREELINE?Roi.POLYLINE:Roi.POLYGON;
93 if (type==Roi.POLYLINE && distance>0.0) {
98 PolygonRoi p =
new PolygonRoi(x, y, i2, type);
103 double rodbard(
double x) {
110 ex = Math.exp(Math.log(x/700.0)*0.88);
116 float[] getCurvature(
int[] x,
int[] y,
int n) {
117 float[] x2 =
new float[n];
118 float[] y2 =
new float[n];
119 for (
int i=0; i<n; i++) {
123 ImageProcessor ipx =
new FloatProcessor(n, 1, x2, null);
124 ImageProcessor ipy =
new FloatProcessor(n, 1, y2, null);
125 ipx.convolve(kernel, kernel.length, 1);
126 ipy.convolve(kernel, kernel.length, 1);
127 float[] indexes =
new float[n];
128 float[] curvature =
new float[n];
129 for (
int i=0; i<n; i++) {
131 curvature[i] = (float)Math.sqrt((x2[i]-x[i])*(x2[i]-x[i])+(y2[i]-y[i])*(y2[i]-y[i]));
140 void drawEllipse(ImagePlus imp) {
141 IJ.showStatus(
"Fitting ellipse");
142 Roi roi = imp.getRoi();
143 ImageProcessor ip = imp.getProcessor();
144 ImageStatistics stats = imp.getStatistics();
145 EllipseFitter ef =
new EllipseFitter();
148 imp.setRoi(
new PolygonRoi(ef.xCoordinates, ef.yCoordinates, ef.nCoordinates, roi.FREEROI));
152 void convexHull(ImagePlus imp) {
153 Roi roi = imp.getRoi();
154 int type = roi!=null?roi.getType():-1;
155 if (!(type==Roi.FREEROI||type==Roi.TRACED_ROI||type==Roi.POLYGON))
156 {IJ.showMessage(
"Convex Hull",
"Polygonal selection required");
return;}
157 imp.setRoi(makeConvexHull(imp, (PolygonRoi)roi));
161 Roi makeConvexHull(ImagePlus imp, PolygonRoi roi) {
162 int n = roi.getNCoordinates();
163 int[] xCoordinates = roi.getXCoordinates();
164 int[] yCoordinates = roi.getYCoordinates();
165 Rectangle r = roi.getBounds();
168 int[] xx =
new int[n];
169 int[] yy =
new int[n];
171 int p1 = findFirstPoint(xCoordinates, yCoordinates, n, imp);
173 int x1, y1, x2, y2, x3, y3, p2, p3;
176 x1 = xCoordinates[p1];
177 y1 = yCoordinates[p1];
178 p2 = p1+1;
if (p2==n) p2=0;
179 x2 = xCoordinates[p2];
180 y2 = yCoordinates[p2];
181 p3 = p2+1;
if (p3==n) p3=0;
183 x3 = xCoordinates[p3];
184 y3 = yCoordinates[p3];
185 determinate = x1*(y2-y3)-y1*(x2-x3)+(y3*x2-y2*x3);
187 {x2=x3; y2=y3; p2=p3;}
197 }
while (p1!=pstart);
198 return new PolygonRoi(xx, yy, n2, roi.POLYGON);
202 int findFirstPoint(
int[] xCoordinates,
int[] yCoordinates,
int n, ImagePlus imp) {
203 int smallestY = imp.getHeight();
205 for (
int i=0; i<n; i++) {
210 int smallestX = imp.getWidth();
212 for (
int i=0; i<n; i++) {
215 if (y==smallestY && x<smallestX) {
223 void createMask(ImagePlus imp) {
224 Roi roi = imp.getRoi();
225 if (roi==null || !roi.isArea())
226 {IJ.showMessage(
"Create Mask",
"Area selection required");
return;}
227 ImagePlus maskImp = IJ.getInstance().getImagePlus();
229 ImageProcessor ip =
new ByteProcessor(imp.getWidth(), imp.getHeight());
231 maskImp =
new ImagePlus(
"Mask", ip);
234 ImageProcessor ip = maskImp.getProcessor();
237 ip.fill(ip.getMask());
238 maskImp.updateAndDraw();
241 void invert(ImagePlus imp) {
243 {IJ.showMessage(
"Inverse",
"Java 1.2 or later required");
return;}
244 Roi roi = imp.getRoi();
245 if (roi==null || !roi.isArea())
246 {IJ.showMessage(
"Inverse",
"Area selection required");
return;}
248 if (roi instanceof ShapeRoi)
251 s1 =
new ShapeRoi(roi);
253 s2 =
new ShapeRoi(
new Roi(0,0, imp.getWidth(), imp.getHeight()));
254 imp.setRoi(s1.xor(s2));