/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 }