/Users/lyon/j4p/src/ip/gui/frames/EdgeFrame.java
|
1 package ip.gui.frames;
2
3 import futils.WriterUtil;
4 import ip.gui.Doable;
5 import ip.gui.dialog.DoLog;
6 import ip.transforms.ConvolutionUtils;
7 import ip.transforms.Gauss;
8 import ip.transforms.Kernels;
9 import ip.transforms.TransformTable;
10 import j2d.ShortImageBean;
11 import j2d.edge.gabor.FilterCanvas;
12 import math.Mat2;
13 import utils.Timer;
14
15 import java.awt.*;
16 import java.awt.event.ActionEvent;
17 import java.io.FileOutputStream;
18 import java.io.PrintWriter;
19
20
21 public class EdgeFrame extends SpatialFilterFrame
22 implements Doable {
23
24 private Menu laplacianMenu = getMenu("Laplacian");
25 private Menu edgeMenu = getMenu("Edge");
26 private Menu templateMenu = getMenu("Template");
27 private Menu threshMenu = getMenu("Threshold");
28
29
30 private MenuItem laplacian5_mi = addMenuItem(laplacianMenu,
31 "[E-T-4] 5");
32 private MenuItem laplacian3_mi = addMenuItem(laplacianMenu,
33 "[E-T-5] 3");
34 private MenuItem laplacian3Minus_mi = addMenuItem(laplacianMenu,
35 "[E-T-6] 3 Minus");
36 private MenuItem laplacian3Prewitt_mi = addMenuItem(laplacianMenu,
37 "[E-T-p]3Prewitt");
38 private MenuItem laplacian3_4_mi = addMenuItem(laplacianMenu,
39 "[E-T-l]3_4");
40 private MenuItem laplacian9_mi = addMenuItem(laplacianMenu,
41 "[E-T-7]9");
42 private MenuItem hat13_mi = addMenuItem(laplacianMenu,
43 "[E-T-8]hat 13x13");
44 private MenuItem hat13v2_mi = addMenuItem(laplacianMenu,
45 "[E-T-8]hat 13x13 v2");
46
47 private MenuItem pixelDifference_mi = addMenuItem(templateMenu,
48 "Pixel Difference");
49 private MenuItem roberts2_mi = addMenuItem(edgeMenu,
50 "[E-T-r]oberts 2");
51 private MenuItem mosaic_mi = addMenuItem(edgeMenu, "mosaic");
52 private MenuItem medianSquare2x2_mi = addMenuItem(edgeMenu,
53 "[E-)]medianSquare2x2 ");
54 private MenuItem median2x1_mi = addMenuItem(edgeMenu,
55 "[E-}]median2x1");
56 private MenuItem median1x2_mi = addMenuItem(edgeMenu,
57 "[E-{]median1x2");
58 private MenuItem magOfDerivativeOfGauss13_mi = addMenuItem(edgeMenu,
59 "magOfDerivativeOfGauss13");
60
61
62 private MenuItem sobel3_mi = addMenuItem(templateMenu,
63 "[E-T-2]Sobel3");
64 private MenuItem separatedPixelDifference_mi =
65 addMenuItem(templateMenu, "Separated Pixel Difference");
66 private MenuItem prewitt_mi = addMenuItem(templateMenu, "Prewitt");
67
68 private MenuItem freiChen_mi = addMenuItem(templateMenu, "Frei-Chen");
69
70 private MenuItem zeroCross_mi = addMenuItem(edgeMenu,
71 "[E-T-z]eroCross");
72 private MenuItem sizeDetector_mi = addMenuItem(edgeMenu,
73 "[E-T-s]ize detector");
74 private MenuItem printVariance_mi = addMenuItem(edgeMenu,
75 "[E-T-p]rintVariance");
76
77
78 private MenuItem printSigma_mi = addMenuItem(edgeMenu, "printSigma");
79
80 private MenuItem thresh_mi = addMenuItem(threshMenu, "[E-T-9]thresh");
81 private MenuItem threshold_mi = addMenuItem(threshMenu,
82 "[E-T]hreshold...");
83
84
85 public void actionPerformed(ActionEvent e) {
86
87 if (match(e, mosaic_mi)) {
88 mosaic();
89 return;
90 }
91
92 if (match(e, magOfDerivativeOfGauss13_mi)) {
93 magOfDerivativeOfGauss13();
94 return;
95 }
96 if (match(e, median2x1_mi)) {
97 median2x1();
98 return;
99 }
100 if (match(e, median1x2_mi)) {
101 median1x2();
102 return;
103 }
104 if (match(e, medianSquare2x2_mi)) {
105 medianSquare2x2();
106 return;
107 }
108 if (match(e, freiChen_mi)) {
109 freiChen();
110 return;
111 }
112 if (match(e, prewitt_mi)) {
113 prewitt();
114 return;
115 }
116 if (match(e, separatedPixelDifference_mi)) {
117 separatedPixelDifference();
118 return;
119 }
120 if (match(e, threshold_mi)) {
121 threshLog();
122 return;
123 }
124
125 if (match(e, pixelDifference_mi)) {
126 pixelDifference();
127 return;
128 }
129 if (match(e, roberts2_mi)) {
130 roberts2();
131 return;
132 }
133 if (match(e, printSigma_mi)) {
134 printSigma();
135 return;
136 }
137 if (match(e, printVariance_mi)) {
138 printVariance();
139 return;
140 }
141 if (match(e, laplacian3_4_mi)) {
142 laplacian3_4();
143 return;
144 }
145 if (match(e, sizeDetector_mi)) {
146 sizeDetector();
147 return;
148 }
149 if (match(e, zeroCross_mi)) {
150 zeroCross();
151 return;
152 }
153 if (match(e, laplacian3Prewitt_mi)) {
154 laplacian3Prewitt();
155 return;
156 }
157 if (match(e, laplacian3Minus_mi)) {
158 laplacian3Minus();
159 return;
160 }
161 if (match(e, thresh_mi)) {
162 thresh();
163 return;
164 }
165 if (match(e, sobel3_mi)) {
166 sobel3();
167 return;
168 }
169 if (match(e, hat13v2_mi)) {
170 hat13v2();
171 return;
172 }
173 if (match(e, hat13_mi)) {
174 hat13();
175 return;
176 }
177 if (match(e, shadowMask_mi)) {
178 shadowMask1();
179 return;
180 }
181 if (match(e, laplacian3_mi)) {
182 laplacian3();
183 return;
184 }
185 if (match(e, laplacian5_mi)) {
186 laplacian5();
187 return;
188 }
189 if (match(e, laplacian9_mi)) {
190 laplacian9();
191 return;
192 }
193
194 super.actionPerformed(e);
195
196 }
197
198 public EdgeFrame(String title) {
199 super(title);
200 edgeMenu.add(threshMenu);
201 edgeMenu.add(laplacianMenu);
202 edgeMenu.add(templateMenu);
203 getSpatialFilterMenu().add(edgeMenu);
204 }
205
206 public void medianSquare2x2() {
207 short k[][] = {
208 {(short) 1, 1, 0},
209 {(short) 1, 1, 0},
210 {(short) 0, 0, 0}
211 };
212 median(k);
213 }
214
215 // Note to the reader...
216 // the private Magnitude of Gaussian stuff
217 // is experimental stuff...DL
218 public void magOfDerivativeOfGauss13() {
219 float k[][] = Gauss.getMagnitudeOfTheDerivativeOfGauss(13,
220 13,
221 1.0);
222 System.out.println("Experimental!!");
223 convolve(k);
224 }
225
226 public void median2x1() {
227 short[][] k = Kernels.getMedian2x1();
228 median(k);
229 }
230
231 public void median1x2() {
232 short[][] k = Kernels.getMedian1x2();
233 median(k);
234 }
235
236 public void roberts2() {
237 ShortImageBean.colorToRed(shortImageBean);
238 int p[] = new int[4];
239 float delta_u = 0;
240 float delta_v = 0;
241 short t;
242 for (int x = 0; x < getImageWidth() - 1; x++)
243 for (int y = 0; y < getImageHeight() - 1; y++) {
244 p[0] = shortImageBean.getR()[x][y];
245 p[1] = shortImageBean.getR()[x + 1][y];
246 p[2] = shortImageBean.getR()[x][y + 1];
247 p[3] = shortImageBean.getR()[x + 1][y + 1];
248 delta_u = p[0] - p[3];
249 delta_v = p[1] - p[2];
250 t = (short)
251 Math.sqrt(delta_u * delta_u + delta_v * delta_v);
252 //if (t > 48) t = 255;
253 //else t=0;
254 shortImageBean.getR()[x][y] = t;
255 shortImageBean.getG()[x][y] = t;
256 shortImageBean.getB()[x][y] = t;
257 }
258 short2Image();
259
260 }
261
262 public static void roberts2(ShortImageBean sib) {
263 ShortImageBean.colorToRed(sib);
264 int p[] = new int[4];
265 float delta_u = 0;
266 float delta_v = 0;
267 short t;
268 for (int x = 0; x < sib.getWidth() - 1; x++)
269 for (int y = 0; y < sib.getHeight() - 1; y++) {
270 p[0] = sib.getR()[x][y];
271 p[1] = sib.getR()[x + 1][y];
272 p[2] = sib.getR()[x][y + 1];
273 p[3] = sib.getR()[x + 1][y + 1];
274 delta_u = p[0] - p[3];
275 delta_v = p[1] - p[2];
276 t = (short)
277 Math.sqrt(delta_u * delta_u + delta_v * delta_v);
278 //if (t > 48) t = 255;
279 //else t=0;
280 sib.getR()[x][y] = t;
281 sib.getG()[x][y] = t;
282 sib.getB()[x][y] = t;
283 }
284 }
285
286 public void mosaic() {
287 FilterCanvas.getSubBands(getImage(), this);
288 }
289
290 public void shadowMask1() {
291 convolve(Kernels.getRobinson1());
292 }
293
294
295 public void sizeDetector() {
296 short[][] r = Kernels.getSizeDetector(shortImageBean.getR());
297 shortImageBean.setR(r);
298 setG(Kernels.getSizeDetector(shortImageBean.getG()));
299 setB(Kernels.getSizeDetector(shortImageBean.getB()));
300 short2Image();
301 }
302
303 public void sobel3() {
304 float k1[][] = Kernels.getRobinson3();
305 float k2[][] = Kernels.getRobinson1();
306 templateEdge(k1, k2);
307 }
308
309 public void separatedPixelDifference() {
310 float k1[][] = {
311 {(float) 0, 0, 0},
312 {(float) 1, 0, -1},
313 {(float) 0, 0, 0}
314 };
315 float k2[][] = {
316 {(float) 0, -1, 0},
317 {(float) 0, 0, 0},
318 {(float) 0, 1, 0}
319 };
320 templateEdge(k1, k2);
321 }
322
323 public void prewitt() {
324 float k1[][] = {
325 {(float) 1, 0, -1},
326 {(float) 1, 0, -1},
327 {(float) 1, 0, -1}
328 };
329
330 float k2[][] = {
331 {(float) -1, -1, -1},
332 {(float) 0, 0, 0},
333 {(float) 1, 1, 1}
334 };
335 Mat2.scale(k1, 1 / 3.0);
336 Mat2.scale(k2, 1 / 3.0);
337 templateEdge(k1, k2);
338 }
339
340 public void freiChen() {
341 float r2 = (float) Math.sqrt(2);
342 float k1[][] = {
343 {(float) 1, 0, -1},
344 {r2, 0, -r2},
345 {(float) 1, 0, -1}
346 };
347
348 float k2[][] = {
349 {(float) -1, -r2, -1},
350 {(float) 0, 0, 0},
351 {(float) 1, r2, 1}
352 };
353 double s = 1 / (2 + r2);
354 Mat2.scale(k1, s);
355 Mat2.scale(k2, s);
356 templateEdge(k1, k2);
357 }
358
359 public void pixelDifference() {
360 float k1[][] = {
361 {(float) 0, 0, 0},
362 {(float) 0, 1, -1},
363 {(float) 0, 0, 0}
364 };
365 float k2[][] = {
366 {(float) 0, -1, 0},
367 {(float) 0, 1, 0},
368 {(float) 0, 0, 0}
369 };
370 templateEdge(k1, k2);
371 }
372
373
374 public void templateEdge(float k1[][], float k2[][]) {
375 ShortImageBean.colorToRed(shortImageBean);
376 //printMaple(k1,"k1=");
377 //printMaple(k2,"k2=");
378 setG(ConvolutionUtils.convolve2(shortImageBean.getR(), k1));
379 setB(ConvolutionUtils.convolve2(shortImageBean.getR(), k2));
380 short t = 0;
381 for (int x = 0; x < getImageWidth(); x++)
382 for (int y = 0; y < getImageHeight(); y++) {
383 t =
384 (short) Math.sqrt(
385 shortImageBean.getG()[x][y] *
386 shortImageBean.getG()[x][y] +
387 shortImageBean.getB()[x][y] *
388 shortImageBean.getB()[x][y]);
389 shortImageBean.getR()[x][y] = t;
390 shortImageBean.getG()[x][y] = t;
391 shortImageBean.getB()[x][y] = t;
392 }
393 short2Image();
394 }
395
396 public void printMaple(float a[][], String prefix) {
397 System.out.print(prefix);
398 Mat2.printMaple(a);
399 }
400
401 public void laplacian5() {
402 float[][] k = Kernels.getLaplacian5();
403 convolve(k);
404 }
405
406 public void laplacian3() {
407 float[][] k = Kernels.getLaplacian3();
408 convolve(k);
409 }
410
411 public void laplacian3Prewitt() {
412 float[][] k = Kernels.getLaplacianPrewitt();
413 //Mat.scale(k,1/8.0);
414 convolve(k);
415 }
416
417 public void laplacian3_4() {
418 float k[][] = {
419 {(float) 1, -2, 1},
420 {(float) -2, 4, -2},
421 {(float) 1, -2, 1}
422 };
423 convolve(k);
424 }
425
426 public void laplacian3Minus() {
427 float k[][] = {
428 {(float) 0, 1, 0},
429 {(float) 1, -4, 1},
430 {(float) 0, 1, 0}
431 };
432 convolve(k);
433 }
434
435 public void tGenerator(int min, int max) {
436 String fn = WriterUtil.getSaveFileName("t.java generator");
437 try {
438 FileOutputStream fos =
439 new FileOutputStream(fn);
440 PrintWriter ps = new PrintWriter(fos);
441 for (int i = min; i < max; i++)
442 ps.println("static double t"
443 + i + " = 0;");
444 fos.close();
445 } catch (Exception e) {
446 }
447 ;
448 }
449
450 public static void main(String args[]) {
451 EdgeFrame ef = new EdgeFrame("Edge Frame");
452 ef.show();
453 ef.tGenerator(0, 2000);
454 }
455
456 public void thresh() {
457 Mat2.threshold(shortImageBean.getR());
458 Mat2.threshold(shortImageBean.getG());
459 Mat2.threshold(shortImageBean.getB());
460 short2Image();
461 }
462
463 public void convolveZeroCross(float k[] []) {
464 // a 1kx1k image allocates not more than
465 // 1 MB at a time.
466 //Mat.print(k);
467 short[][] r = convolveZeroCross(shortImageBean.getR(), k);
468 shortImageBean.setR(r);
469 setG(convolveZeroCross(shortImageBean.getG(), k));
470 setB(convolveZeroCross(shortImageBean.getB(), k));
471 short2Image();
472 }
473
474 public void zeroCross() {
475 // a 1kx1k image allocates not more than
476 // 1 MB at a time.
477 //Mat.print(k);
478 short[][] r = zeroCross(shortImageBean.getR());
479 shortImageBean.setR(r);
480 setG(zeroCross(shortImageBean.getG()));
481 setB(zeroCross(shortImageBean.getB()));
482 short2Image();
483 }
484
485 public short[][] convolveZeroCross(short a[][], float k[][]) {
486 a = ConvolutionUtils.convolve2(a, k);
487 a = zeroCross(a);
488 return a;
489 }
490
491 // p0 p1 p2
492 // p3 p4 p5
493 // p6 p7 p8
494 //
495 //
496 public short[][] zeroCross(short f[][]) {
497 short a[][] = new short[f.length][f[0].length];
498 int p[] = new int[9];
499 for (int x = 1; x < f.length - 1; x++)
500 for (int y = 1; y < f[0].length - 1; y++) {
501 p[1] = f[x][y + 1];
502 p[3] = f[x - 1][y];
503 p[5] = f[x + 1][y];
504 p[7] = f[x][y - 1];
505 if (((p[1] < 0) && (p[7] >= 0)) ||
506 ((p[1] >= 0) && (p[7] < 0)) ||
507 ((p[3] < 0) && (p[5] >= 0)) ||
508 ((p[3] >= 0) && (p[5] < 0)))
509 a[x][y] = 255;
510 }
511 return a;
512 }
513
514
515 public void laplacian9() {
516 float[][] k = Kernels.getLaplacian9();
517 //sum=0.0
518 convolve(k);
519 }
520
521
522 public void hat13v2() {
523 float k[][] = Kernels.getLaplaceOfGaussianKernel(13, 13, 2.0);
524 convolve(k);
525 //Mat.printKernel(k,"hat13v2"+k.length);
526 }
527
528 public void hat13() {
529 // Hat13 filter
530 float[][] k = Kernels.getHat13();
531 Timer t = new Timer();
532 t.start();
533 convolve(k);
534
535 t.print("laplace convolution");
536 //Mat.printKernel(k,"hat13"+k.length);
537 }
538
539 public void horizontalSegment() {
540 float mask [][] = {
541 {(float) 0, 0, 0},
542 {(float) 1, 1, 1},
543 {(float) 0, 0, 0}
544 };
545 Mat2.normalize(mask);
546 convolve(mask);
547 }
548
549 public void verticalSegment() {
550 float mask [][] = {
551 {(float) 0, 1, 0},
552 {(float) 0, 1, 0},
553 {(float) 0, 1, 0}
554 };
555 Mat2.normalize(mask);
556 convolve(mask);
557 }
558
559 protected void printVariance() {
560 System.out.println(
561 "variance(r)=" + Mat2.variance(shortImageBean.getR()));
562 System.out.println(
563 "variance(g)=" + Mat2.variance(shortImageBean.getG()));
564 System.out.println(
565 "variance(b)=" + Mat2.variance(shortImageBean.getB()));
566 }
567
568 protected double sigma(short a[][]) {
569 return Math.sqrt(Mat2.variance(a));
570 }
571
572 protected void printSigma() {
573 System.out.println("Sigma(r)=" + sigma(shortImageBean.getR()));
574 System.out.println("Sigma(g)=" + sigma(shortImageBean.getG()));
575 System.out.println("Sigma(b)=" + sigma(shortImageBean.getB()));
576 }
577
578 public void threshLog() {
579 String prompts[] = {
580 "t1", "t2",
581 "t3", "t4",
582 "K=#grays, overrides above"};
583 String defaults[] = {
584 "60", "120",
585 "180", "240",
586 "0"};
587 int fieldSize = 6;
588 new DoLog(this, "Threshold Dialog",
589 prompts, defaults, fieldSize);
590 }
591
592 public void doit(double d[]) {
593 if (d[4] != 0)
594 kgreyThresh(d[4]);
595 else
596 thresh4(d);
597 }
598
599 public void kgreyThresh(double k) {
600 HistogramFrame rh = new HistogramFrame(shortImageBean.getR(),
601 "red");
602 double cmf[] = rh.getCMF();
603 TransformTable tt = new TransformTable(cmf.length);
604 short lut[] = tt.getLut();
605 int q = 1;
606 short v = 0;
607 short dv = (short) (255 / k);
608 for (int i = 0; i < lut.length; i++) {
609 if (cmf[i] > q / k) {
610 v += dv;
611 q++; //(k == q+1)||
612 if (q == k) v = 255;
613 }
614 lut[i] = v;
615 }
616 tt.setLut(lut);
617 tt.clip();
618 //tt.print();
619 applyLut(lut);
620 }
621
622 public void thresh4(double d[]) {
623 short lut[] = new short[256];
624 if (d[4] == 0)
625 for (int i = 0; i < lut.length; i++) {
626 if (i < d[0])
627 lut[i] = 0;
628 else if (i < d[1])
629 lut[i] = (short) d[0];
630 else if (i < d[2])
631 lut[i] = (short) d[1];
632 else if (i < d[3])
633 lut[i] = (short) d[2];
634 else
635 lut[i] = 255;
636 //System.out.println(lut[i]);
637 }
638 applyLut(lut);
639 }
640
641
642 }