/Users/lyon/j4p/src/j2d/edge/CannyProcessor.java
|
1 // Decompiled by Jad v1.5.8c. Copyright 2001 Pavel Kouznetsov.
2 // Jad home page: http://www.geocities.com/kpdus/jad.html
3 // Decompiler options: packimports(3)
4 // Source File Name: EdgeDetector.java
5
6 package j2d.edge;
7
8 import j2d.ImageProcessorInterface;
9 import j2d.ImageProcessorFactory;
10
11 import java.awt.*;
12
13
14 public class CannyProcessor
15 implements ImageProcessorInterface,
16 ImageProcessorFactory {
17
18 private int imagePels[];
19 private int derivativeOfMag[];
20 private int magnitude[];
21 private int orientation[];
22
23 private int tLow = 50;
24 private int tHi = 230;
25 private int threshold = 128;
26 private int widGaussianKernel = 15;
27 private float sigma = 1.0f;
28
29 public CannyProcessor(int thresh1,
30 int thresh2,
31 int thresh,
32 int kw,
33 float sigma) {
34 tLow = thresh1;
35 tHi = thresh2;
36 threshold = thresh;
37 widGaussianKernel = kw;
38 this.sigma = sigma;
39 }
40
41 public ImageProcessorInterface getProcessor(int i) {
42 return new CannyProcessor(tLow, tHi, threshold,
43 widGaussianKernel, i);
44 }
45
46 public Image process(Image _sourceImage) {
47 Image sourceImage = _sourceImage;
48 if (threshold < 0 || threshold > 255)
49 futils.Out.messageDialog("The value of the threshold is out of its valid range.");
50 if (widGaussianKernel < 3 || widGaussianKernel > 40)
51 futils.Out.messageDialog("The value of the widGaussianKernel is out of its valid range.");
52 int width = sourceImage.getWidth(null);
53 int height = sourceImage.getHeight(null);
54 int picsize = width * height;
55 imagePels = new int[picsize];
56 magnitude = new int[picsize];
57 orientation = new int[picsize];
58
59 cannyCore(width, height, sourceImage, sigma, widGaussianKernel);
60 edgeDetect(width, height);
61 for (int i = 0; i < picsize; i++)
62 if (imagePels[i] > threshold)
63 imagePels[i] = 0xff000000;
64 else
65 imagePels[i] = -1;
66
67 return j2d.ImageUtils.getImage(
68 imagePels, width, height);
69 }
70
71 private void cannyCore(int width,
72 int height,
73 Image sourceImage,
74 float sigma,
75 int i) {
76 boolean flag = false;
77 boolean flag1 = false;
78 int picsize = width * height;
79 derivativeOfMag = new int[picsize];
80 float af4[] = new float[i];
81 float af3[] = new float[i];
82 float af6[] = new float[i];
83 imagePels = j2d.ImageUtils.getPels(sourceImage);
84 int k4 = 0;
85 do {
86 if (k4 >= i)
87 break;
88 float f1 = gaussian(k4, sigma);
89 if (f1 <= 0.005F && k4 >= 2)
90 break;
91 float f2 = gaussian((float) k4 - 0.5F, sigma);
92 float f3 = gaussian((float) k4 + 0.5F, sigma);
93 float f4 = gaussian(k4, sigma * 0.5F);
94 af4[k4] = (f1 + f2 + f3) / 3F / (6.283185F * sigma * sigma);
95 af3[k4] = f3 - f2;
96 af6[k4] = 1.6F * f4 - f1;
97 k4++;
98 } while (true);
99 int j = k4;
100 float af[] = new float[picsize];
101 float af1[] = new float[picsize];
102 int j1 = width - (j - 1);
103 int l = width * (j - 1);
104 int i1 = width * (height - (j - 1));
105 for (int l4 = j - 1; l4 < j1; l4++) {
106 for (int l5 = l; l5 < i1; l5 += width) {
107 int k1 = l4 + l5;
108 float f8 = (float) imagePels[k1] * af4[0];
109 float f10 = f8;
110 int l6 = 1;
111 int k7 = k1 - width;
112 for (int i8 = k1 + width; l6 < j; i8 += width) {
113 f8 += af4[l6] * (float) (imagePels[k7] + imagePels[i8]);
114 f10 += af4[l6] * (float) (imagePels[k1 - l6] + imagePels[k1 + l6]);
115 l6++;
116 k7 -= width;
117 }
118
119 af[k1] = f8;
120 af1[k1] = f10;
121 }
122
123 }
124
125 float[] af2 = getAf2(picsize, j, j1, l, i1, af3, af, width);
126
127 af = null;
128 af3 = getAf3(picsize, k4, width, l, i1, j, af3, af1);
129
130 af1 = null;
131 j1 = width - j;
132 l = width * j;
133 i1 = width * (height - j);
134 for (int k5 = j; k5 < j1; k5++) {
135 for (int k6 = l; k6 < i1; k6 += width) {
136 int j2 = k5 + k6;
137 int k2 = j2 - width;
138 int l2 = j2 + width;
139 int i3 = j2 - 1;
140 int j3 = j2 + 1;
141 int k3 = k2 - 1;
142 int l3 = k2 + 1;
143 int i4 = l2 - 1;
144 int j4 = l2 + 1;
145 float f6 = af2[j2];
146 float f7 = af3[j2];
147 float f12 = hypotenuse(f6, f7);
148 int k = (int) ((double) f12 * 20D);
149 derivativeOfMag[j2] = k >= 256 ? 255 : k;
150 float f13 = hypotenuse(af2[k2], af3[k2]);
151 float f14 = hypotenuse(af2[l2], af3[l2]);
152 float f15 = hypotenuse(af2[i3], af3[i3]);
153 float f16 = hypotenuse(af2[j3], af3[j3]);
154 float f18 = hypotenuse(af2[l3], af3[l3]);
155 float f20 = hypotenuse(af2[j4], af3[j4]);
156 float f19 = hypotenuse(af2[i4], af3[i4]);
157 float f17 = hypotenuse(af2[k3], af3[k3]);
158 float f5;
159 if (f6 * f7 <= (float) 0 ? Math.abs(f6) >= Math.abs(f7) ? (f5 = Math.abs(f6 * f12)) >= Math.abs(f7 * f18 - (f6 + f7) * f16) && f5 > Math.abs(f7 * f19 - (f6 + f7) * f15) : (f5 = Math.abs(f7 * f12)) >= Math.abs(f6 * f18 - (f7 + f6) * f13) && f5 > Math.abs(f6 * f19 - (f7 + f6) * f14) : Math.abs(f6) >= Math.abs(f7) ? (f5 = Math.abs(f6 * f12)) >= Math.abs(f7 * f20 + (f6 - f7) * f16) && f5 > Math.abs(f7 * f17 + (f6 - f7) * f15) : (f5 = Math.abs(f7 * f12)) >= Math.abs(f6 * f20 + (f7 - f6) * f14) && f5 > Math.abs(f6 * f17 + (f7 - f6) * f13)) {
160 magnitude[j2] = derivativeOfMag[j2];
161 orientation[j2] = (int) (
162 Math.atan2(f7, f6) * (double) 40F);
163 }
164 }
165
166 }
167
168 derivativeOfMag = null;
169 af2 = null;
170 af3 = null;
171 }
172
173 private float[] getAf3(int picsize, int k4, int width, int l, int i1, int j, float[] af5, float[] af1) {
174 float af3[] = new float[picsize];
175 for (int j5 = k4; j5 < width - k4; j5++) {
176 for (int j6 = l; j6 < i1; j6 += width) {
177 float f11 = 0.0F;
178 int i2 = j5 + j6;
179 int j7 = 1;
180 for (int l7 = width; j7 < j; l7 += width) {
181 f11 += af5[j7] * (af1[i2 - l7] - af1[i2 + l7]);
182 j7++;
183 }
184
185 af3[i2] = f11;
186 }
187
188 }
189 return af3;
190 }
191
192 private float[] getAf2(int picsize, int j, int j1, int l, int i1, float[] af5, float[] af, int width) {
193 float af2[] = new float[picsize];
194 for (int i5 = j - 1; i5 < j1; i5++) {
195 for (int i6 = l; i6 < i1; i6 += width) {
196 float f9 = 0.0F;
197 int l1 = i5 + i6;
198 for (int i7 = 1; i7 < j; i7++)
199 f9 += af5[i7] * (af[l1 - i7] - af[l1 + i7]);
200
201 af2[l1] = f9;
202 }
203
204 }
205 return af2;
206 }
207
208 private float hypotenuse(float f, float f1) {
209 if (f == 0.0F && f1 == 0.0F)
210 return 0.0F;
211 else
212 return (float) Math.sqrt(f * f + f1 * f1);
213 }
214
215 private float gaussian(float f, float sigma) {
216 return (float) Math.exp((-f * f) / ((float) 2 * sigma * sigma));
217 }
218
219 private void edgeDetect(int width, int height) {
220 int picsize = width * height;
221 imagePels = new int[picsize];
222
223 for (int x = 0; x < width; x++) {
224 for (int y = 0; y < height; y++)
225 if (magnitude[x + width * y] >= tLow)
226 followEdge(width, height, x, y);
227
228 }
229
230 }
231
232 private boolean followEdge(int width, int height, int x, int y) {
233 int j1 = x + 1;
234 int k1 = x - 1;
235 int l1 = y + 1;
236 int i2 = y - 1;
237 int j2 = x + y * width;
238 if (l1 >= height)
239 l1 = height - 1;
240 if (i2 < 0)
241 i2 = 0;
242 if (j1 >= width)
243 j1 = width - 1;
244 if (k1 < 0)
245 k1 = 0;
246 if (imagePels[j2] == 0) {
247 imagePels[j2] = magnitude[j2];
248 boolean flag = false;
249 int l = k1;
250 do {
251 if (l > j1)
252 break;
253 int i1 = i2;
254 do {
255 if (i1 > l1)
256 break;
257 int k2 = l + i1 * width;
258 if ((i1 != y || l != x) && magnitude[k2] >= tHi &&
259 followEdge(width, height, l, i1)) {
260 flag = true;
261 break;
262 }
263 i1++;
264 } while (true);
265 if (!flag)
266 break;
267 l++;
268 } while (true);
269 return true;
270 } else {
271 return false;
272 }
273 }
274
275
276 }
277