/Users/lyon/j4p/src/ip/transforms/Kernels.java

1    package ip.transforms; 
2     
3    import math.Mat2; 
4     
5     
6    public final class Kernels { 
7        private Kernels() { 
8        } 
9     
10       private static double robinsonScaleFactor = .25; 
11    
12       // Robinson level 5 detector, see Pratt. 
13       public static float[][] getRobinson1() { 
14           float k[][] = { 
15               {(float) 1, 0, -1}, 
16               {(float) 2, 0, -2}, 
17               {(float) 1, 0, -1} 
18           }; 
19           Mat2.scale(k, robinsonScaleFactor); 
20           return k; 
21       } 
22    
23       public static float[][] getRobinson2() { 
24           float k[][] = { 
25               {(float) 0, -1, -2}, 
26               {(float) 1, 0, -1}, 
27               {(float) 2, 1, 0} 
28           }; 
29           Mat2.scale(k, robinsonScaleFactor); 
30           return k; 
31       } 
32    
33       public static float[][] getSobel() { 
34           float k[][] = { 
35               {(float) -1, -1, -1}, 
36               {(float) -1, 8, -1}, 
37               {(float) -1, -1, -1} 
38           }; 
39           return k; 
40       } 
41    
42       public static float[][] getSobelX(int a) { 
43           float k[][] = { 
44               {(float) -1, 0, 1}, 
45               {(float) -a, 0, a}, 
46               {(float) -1, 0, 1} 
47           }; 
48           return k; 
49       } 
50    
51       public static float[][] getSobelY(int a) { 
52           float k[][] = { 
53               {(float) -1, -a, 1}, 
54               {(float) 0, 0, 0}, 
55               {(float) 1, a, 1} 
56           }; 
57           return k; 
58       } 
59    
60    
61       public static float[][] getRobinson3() { 
62           float k[][] = { 
63               {(float) -1, -2, -1}, 
64               {(float) 0, 0, 0}, 
65               {(float) 1, 2, 1} 
66           }; 
67           Mat2.scale(k, robinsonScaleFactor); 
68           return k; 
69       } 
70    
71       public static float[][] getRobinson4() { 
72           float k[][] = { 
73               {(float) -2, -1, 0}, 
74               {(float) -1, 0, 1}, 
75               {(float) 0, 1, 2} 
76           }; 
77           Mat2.scale(k, robinsonScaleFactor); 
78           return k; 
79       } 
80    
81       public static float[][] getRobinson5() { 
82           float k[][] = { 
83               {(float) -1, 0, 1}, 
84               {(float) -2, 0, 2}, 
85               {(float) -1, 0, 1} 
86           }; 
87           Mat2.scale(k, robinsonScaleFactor); 
88           return k; 
89       } 
90    
91       public static float[][] getRobinson6() { 
92           float k[][] = { 
93               {(float) 0, 1, 2}, 
94               {(float) -1, 0, 1}, 
95               {(float) -2, -1, 0} 
96           }; 
97           Mat2.scale(k, 0.25); 
98           return k; 
99       } 
100   
101      public static float[][] getRobinson7() { 
102          float k[][] = { 
103              {(float) 1, 2, 1}, 
104              {(float) 0, 0, 0}, 
105              {(float) -1, -2, -1} 
106          }; 
107          Mat2.scale(k, robinsonScaleFactor); 
108          return k; 
109      } 
110   
111      public static float[][] getRobinson8() { 
112          float k[][] = { 
113              {(float) 2, 1, 0}, 
114              {(float) 1, 0, -1}, 
115              {(float) 0, -1, -2} 
116          }; 
117          Mat2.scale(k, robinsonScaleFactor); 
118          return k; 
119      } 
120   
121   
122      public static short[][] getMedian2x1() { 
123          short k[][] = { 
124              {(short) 0, 1, 0}, 
125              {(short) 0, 1, 0}, 
126              {(short) 0, 0, 0} 
127          }; 
128          return k; 
129      } 
130   
131      public static short[][] getMedian1x2() { 
132          short k[][] = { 
133              {(short) 0, 0, 0}, 
134              {(short) 1, 1, 0}, 
135              {(short) 0, 0, 0} 
136          }; 
137          return k; 
138      } 
139   
140      // p0 p1 p2 
141      // p3 p4 p5 
142      // p6 p7 p8 
143      // 
144      // 
145      public static short[][] getSizeDetector(short f[][]) { 
146          short a[][] = new short[f.length][f[0].length]; 
147          int p[] = new int[9]; 
148          int sum = 0; 
149          for (int x = 1; x < f.length - 1; x++) 
150              for (int y = 1; y < f[0].length - 1; y++) { 
151                  sum = 0; 
152                  p[0] = f[x - 1][y + 1]; 
153                  p[1] = f[x][y + 1]; 
154                  p[2] = f[x + 1][y + 1]; 
155                  p[3] = f[x - 1][y]; 
156                  p[4] = f[x][y]; 
157                  p[5] = f[x + 1][y]; 
158                  p[6] = f[x - 1][y - 1]; 
159                  p[7] = f[x][y - 1]; 
160                  p[8] = f[x + 1][y - 1]; 
161                  for (int i = 0; i < p.length; i++) 
162                      sum += p[i]; 
163                  if (sum > 255 * 5) 
164                      a[x][y] = 255; 
165                  else 
166                      a[x][y] = 0; 
167              } 
168          return a; 
169      } 
170   
171      public static float[][] getLaplacian5() { 
172          float k[][] = { 
173              {(float) -1, -1, -1, -1, -1}, 
174              {(float) -1, -1, -1, -1, -1}, 
175              {(float) -1, -1, 24, -1, -1}, 
176              {(float) -1, -1, -1, -1, -1}, 
177              {(float) -1, -1, -1, -1, -1} 
178          }; 
179          return k; 
180      } 
181   
182      public static float[][] getLaplacian3() { 
183          float k[][] = { 
184              {(float) 0, -1, 0}, 
185              {(float) -1, 4, -1}, 
186              {(float) 0, -1, 0} 
187          }; 
188          return k; 
189      } 
190   
191      public static float[][] getLaplacianPrewitt() { 
192          float k[][] = { 
193              {(float) -1, -1, -1}, 
194              {(float) -1, 8, -1}, 
195              {(float) -1, -1, -1} 
196          }; 
197          return k; 
198      } 
199   
200      public static double laplaceOfGaussian(double x, 
201                                             double y, 
202                                             double xc, 
203                                             double yc, 
204                                             double sigma) { 
205          ConvolutionUtils.t1 = sigma * sigma; 
206          ConvolutionUtils.t2 = ConvolutionUtils.t1 * ConvolutionUtils.t1; 
207          ConvolutionUtils.t5 = Math.pow(x - xc, 2.0); 
208          ConvolutionUtils.t7 = Math.pow(y - yc, 2.0); 
209          ConvolutionUtils.t11 = 
210                  Math.exp( 
211                          -(ConvolutionUtils.t5 + ConvolutionUtils.t7) / 
212                  ConvolutionUtils.t1 / 
213                  2); 
214          ConvolutionUtils.t13 = 1 / Math.PI; 
215          ConvolutionUtils.t16 = Math.pow(2.0 * x - 2.0 * xc, 2.0); 
216          ConvolutionUtils.t18 = 1 / 
217                  ConvolutionUtils.t2 / 
218                  ConvolutionUtils.t1; 
219          ConvolutionUtils.t20 = ConvolutionUtils.t11 * 
220                  ConvolutionUtils.t13; 
221          ConvolutionUtils.t23 = Math.pow(2.0 * y - 2.0 * yc, 2.0); 
222          ConvolutionUtils.t26 = 
223                  1 / ConvolutionUtils.t2 * 
224                  ConvolutionUtils.t11 * 
225                  ConvolutionUtils.t13 - 
226                  ConvolutionUtils.t16 * 
227                  ConvolutionUtils.t18 * 
228                  ConvolutionUtils.t20 / 
229                  8 - 
230                  ConvolutionUtils.t23 * 
231                  ConvolutionUtils.t18 * 
232                  ConvolutionUtils.t20 / 
233                  8; 
234          return ConvolutionUtils.t26; 
235      } 
236   
237      public static void printLaplaceOfGaussianKernel(int M, int N, 
238                                                      double sigma) { 
239          float k[][] = getLaplaceOfGaussianKernel(M, N, sigma); 
240          Mat2.printKernel(k, "LaplaceOfGaussian" + k.length); 
241      } 
242   
243      public static float[][] getLaplaceOfGaussianKernel(int M, int N, 
244                                                         double sigma) { 
245          float k[][] = new float[M][N]; 
246          int xc = M / 2; 
247          int yc = N / 2; 
248          for (int x = 0; x < k.length; x++) 
249              for (int y = 0; y < k[0].length; y++) 
250                  k[x][y] = (float) laplaceOfGaussian(x, y, xc, yc, sigma); 
251          Mat2.normalize(k); 
252          return k; 
253      } 
254   
255      public static float[][] getLaplacian9() { 
256          float k[][] = { 
257              {(float) -1, -1, -1, -1, -1, -1, -1, -1, -1}, 
258              {(float) -1, -1, -1, -1, -1, -1, -1, -1, -1}, 
259              {(float) -1, -1, -1, -1, -1, -1, -1, -1, -1}, 
260              {(float) -1, -1, -1, 8, 8, 8, -1, -1, -1}, 
261              {(float) -1, -1, -1, 8, 8, 8, -1, -1, -1}, 
262              {(float) -1, -1, -1, 8, 8, 8, -1, -1, -1}, 
263              {(float) -1, -1, -1, -1, -1, -1, -1, -1, -1}, 
264              {(float) -1, -1, -1, -1, -1, -1, -1, -1, -1}, 
265              {(float) -1, -1, -1, -1, -1, -1, -1, -1, -1}}; 
266          return k; 
267      } 
268   
269      public static float[][] getHat13() { 
270          float k [][] = { 
271              {(float) 0, 0, 0, 0, 0, -1, -1, -1, 0, 0, 0, 0, 0}, 
272              {(float) 0, 0, 0, -1, -1, -2, -2, -2, -1, -1, 0, 0, 0}, 
273              {(float) 0, 0, -2, -2, -3, -3, -4, -3, -3, -2, -2, 0, 0}, 
274              {(float) 0, -1, -2, -3, -3, -3, -2, -3, -3, -3, -2, -1, 0}, 
275              {(float) 0, -1, -3, -3, -1, 4, 6, 4, -1, -3, -3, -1, 0}, 
276              {(float) -1, -2, -3, -3, 4, 14, 19, 14, 4, -3, -3, -2, -1}, 
277              {(float) -1, -2, -4, -2, 6, 19, 24, 19, 6, -2, -4, -2, -1}, 
278              {(float) -1, -2, -3, -3, 4, 14, 19, 14, 4, -3, -3, -2, -1}, 
279              {(float) 0, -1, -3, -3, -1, 4, 6, 4, -1, -3, -3, -1, 0}, 
280              {(float) 0, -1, -2, -3, -3, -3, -2, -3, -3, -3, -2, -1, 0}, 
281              {(float) 0, 0, -2, -2, -3, -3, -4, -3, -3, -2, -2, 0, 0}, 
282              {(float) 0, 0, 0, -1, -1, -2, -2, -2, -1, -1, 0, 0, 0}, 
283              {(float) 0, 0, 0, 0, 0, -1, -1, -1, 0, 0, 0, 0, 0}}; 
284          return k; 
285      } 
286   
287      public static float[][] getLp1() { 
288          float k[][] = { 
289              {(float) 1, 1, 1}, 
290              {(float) 1, 2, 1}, 
291              {(float) 1, 1, 1} 
292          }; 
293          Mat2.scale(k, 1 / 10.0); 
294          return k; 
295      } 
296   
297      public static float[][] getLp2() { 
298          float k[][] = { 
299              {(float) 1, 1, 1}, 
300              {(float) 1, 4, 1}, 
301              {(float) 1, 1, 1} 
302          }; 
303          Mat2.scale(k, 1 / 12.0); 
304          return k; 
305      } 
306   
307      public static float[][] getLp3() { 
308          float k[][] = { 
309              {(float) 1, 1, 1}, 
310              {(float) 1, 12, 1}, 
311              {(float) 1, 1, 1} 
312          }; 
313          Mat2.scale(k, 1 / 20.0); 
314          return k; 
315      } 
316   
317      public static float[][] getGabor7() { 
318          float k[][] = { 
319   
320              {(float) 137, 126, 116, 123, 127, 128, 0}, 
321              {(float) 148, 168, 133, 104, 117, 127, 0}, 
322              {(float) 124, 173, 223, 158, 99, 113, 0}, 
323              {(float) 117, 111, 181, 255, 181, 111, 0}, 
324              {(float) 126, 113, 99, 158, 223, 173, 0}, 
325              {(float) 128, 127, 117, 104, 133, 168, 0}, 
326              {(float) 0, 0, 0, 0, 0, 0, 0} 
327          }; 
328          Mat2.normalize(k); 
329          return k; 
330      } 
331   
332      public static float[][] getMean9() { 
333          float s = (float) 81.0; 
334          float k[][] = { 
335              {1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / 
336                  s}, 
337              {1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / 
338                  s}, 
339              {1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / 
340                  s}, 
341              {1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / 
342                  s}, 
343              {1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / 
344                  s}, 
345              {1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / 
346                  s}, 
347              {1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / 
348                  s}, 
349              {1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / 
350                  s}, 
351              {1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / s, 1 / 
352                  s}}; 
353          return k; 
354      } 
355   
356      public static float[][] getMean3() { 
357          float k[][] = { 
358              {0.11111111f, 0.11111111f, 0.11111111f}, 
359              {0.11111111f, 0.11111111f, 0.11111111f}, 
360              {0.11111111f, 0.11111111f, 0.11111111f}}; 
361          return k; 
362      } 
363   
364      public static short[][] getMedianOctagon5x5() { 
365          short k[][] = { 
366              {(short) 0, 1, 1, 1, 0}, 
367              {(short) 1, 1, 1, 1, 1}, 
368              {(short) 1, 1, 1, 1, 1}, 
369              {(short) 1, 1, 1, 1, 1}, 
370              {(short) 0, 1, 1, 1, 0}}; 
371          return k; 
372      } 
373   
374      public static short[][] getMedianDiamond() { 
375          short k[][] = { 
376              {(short) 0, 0, 0, 1, 0, 0, 0}, 
377              {(short) 0, 0, 1, 1, 1, 0, 0}, 
378              {(short) 0, 1, 1, 1, 1, 1, 0}, 
379              {(short) 1, 1, 1, 1, 1, 1, 1}, 
380              {(short) 0, 1, 1, 1, 1, 1, 0}, 
381              {(short) 0, 0, 1, 1, 1, 0, 0}, 
382              {(short) 0, 0, 0, 1, 0, 0, 0}}; 
383          return k; 
384      } 
385   
386      public static short[][] getMedianCross3x3() { 
387          return new short[][]{ 
388              {(short) 0, 1, 0}, 
389              {(short) 1, 1, 1}, 
390              {(short) 0, 1, 0} 
391          }; 
392      } 
393   
394      public static short[][] getMedianCross5x5() { 
395          short k[][] = { 
396              {(short) 1, 1, 1, 1, 1}, 
397              {(short) 1, 1, 1, 1, 1}, 
398              {(short) 1, 1, 1, 1, 1}, 
399              {(short) 1, 1, 1, 1, 1}, 
400              {(short) 1, 1, 1, 1, 1}}; 
401          return k; 
402      } 
403   
404      public static short[][] getMedianCross7x7() { 
405          short k[][] = { 
406              {(short) 0, 0, 0, 1, 0, 0, 0}, 
407              {(short) 0, 0, 0, 1, 0, 0, 0}, 
408              {(short) 0, 0, 0, 1, 0, 0, 0}, 
409              {(short) 1, 1, 1, 1, 1, 1, 1}, 
410              {(short) 0, 0, 0, 1, 0, 0, 0}, 
411              {(short) 0, 0, 0, 1, 0, 0, 0}, 
412              {(short) 0, 0, 0, 1, 0, 0, 0}}; 
413          return k; 
414      } 
415   
416      public static short[][] getMedianSquare7x7() { 
417          short k[][] = { 
418              {(short) 1, 1, 1, 1, 1, 1, 1}, 
419              {(short) 1, 1, 1, 1, 1, 1, 1}, 
420              {(short) 1, 1, 1, 1, 1, 1, 1}, 
421              {(short) 1, 1, 1, 1, 1, 1, 1}, 
422              {(short) 1, 1, 1, 1, 1, 1, 1}, 
423              {(short) 1, 1, 1, 1, 1, 1, 1}, 
424              {(short) 1, 1, 1, 1, 1, 1, 1}}; 
425          return k; 
426      } 
427   
428      public static float[][] getAverage3x3() { 
429          float k[][] = { 
430              {(float) 1, 1, 1}, 
431              {(float) 1, 1, 1}, 
432              {(float) 1, 1, 1} 
433          }; 
434          Mat2.scale(k, 1 / 9.0); 
435          return k; 
436      } 
437   
438      public static float[][] getHp1() { 
439          float k[][] = { 
440              {(float) 0, -1, 0}, 
441              {(float) -1, 10, -1}, 
442              {(float) 0, -1, 0} 
443          }; 
444          Mat2.normalize(k); 
445          return k; 
446      } 
447   
448      public static float[][] getHp2() { 
449          float k[][] = { 
450              {(float) 0, -1, 0}, 
451              {(float) -1, 8, -1}, 
452              {(float) 0, -1, 0} 
453          }; 
454          Mat2.normalize(k); 
455          return k; 
456      } 
457   
458      public static float[][] getHp3() { 
459          float k[][] = { 
460              {(float) 0, -1, 0}, 
461              {(float) -1, 5, -1}, 
462              {(float) 0, -1, 0} 
463          }; 
464          Mat2.normalize(k); 
465          return k; 
466      } 
467   
468      public static float[][] getHp4() { 
469          float k[][] = { 
470              {(float) 1, -2, 1}, 
471              {(float) -2, 5, -2}, 
472              {(float) 1, -2, 1} 
473          }; 
474          return k; 
475      } 
476   
477      public static float[][] getHp5() { 
478          float k[][] = { 
479              {(float) -1, -1, -1}, 
480              {(float) -1, 9, -1}, 
481              {(float) -1, -1, -1} 
482          }; 
483          return k; 
484      } 
485   
486      public static void main(String args[]) { 
487          printMehrotraAndZhang(); 
488      } 
489   
490      public static void printMehrotraAndZhang() { 
491          Mat2.printKernel(getMehrotraAndZhangKernel(9, 9, 1), 
492                  "Mehrotra and Zhang"); 
493      } 
494   
495      public static float[][] getMehrotraAndZhangKernel(int M, int N, 
496                                                        double h) { 
497          float k[][] = new float[M][N]; 
498          double deltaX = 1 / (M * 1.0); 
499          double deltaY = 1 / (N * 1.0); 
500          double startX = -1; 
501          double startY = -1; 
502   
503          for (int x = 0; x < k.length; x++) 
504              for (int y = 0; y < k[0].length; y++) { 
505                  k[x][y] = (float) mehrotraAndZhang(startX + deltaX * x, 
506                          startY + deltaY * y, 
507                          h); 
508              } 
509          Mat2.normalize(k); 
510          return k; 
511      } 
512   
513      /* 
514      -100/9/h**2*(1-(x**2+y**2)**(3/2)/h**3+7.5*(x**2+y**2)**(3/2)/h**3*ln((x**2+ 
515  y**2)**(1/2)/h)) 
516  can be input into maple, optimized and the following will result. 
517  This is the core optimal detector  described by Mehrotra and Zhan on pp6 
518  of Graphical Models and Image Processing, v58, No. 1, Jan. 1996. 
519      */ 
520      public static double mehrotraAndZhang(double x, double y, double h) { 
521          ConvolutionUtils.t1 = h * h; 
522          ConvolutionUtils.t3 = x * x; 
523          ConvolutionUtils.t4 = y * y; 
524          ConvolutionUtils.t5 = ConvolutionUtils.t3 + ConvolutionUtils.t4; 
525          ConvolutionUtils.t6 = Math.sqrt(ConvolutionUtils.t5); 
526          ConvolutionUtils.t7 = ConvolutionUtils.t6 * ConvolutionUtils.t5; 
527          ConvolutionUtils.t9 = 1 / ConvolutionUtils.t1 / h; 
528          return -100.0 / 9.0 / ConvolutionUtils.t1 * 
529                  (1.0 - ConvolutionUtils.t7 * ConvolutionUtils.t9 + 
530                  0.75E1 * 
531                  ConvolutionUtils.t7 * 
532                  ConvolutionUtils.t9 * 
533                  Math.log(ConvolutionUtils.t6 / h)); 
534      } 
535  }