/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