/Users/lyon/j4p/src/ip/gui/frames/BoundaryFrame.java
|
1 package ip.gui.frames;
2
3 import ip.gui.MorphUtils;
4 import ip.transforms.Polygons;
5 import math.Mat2;
6 import utils.Timer;
7
8 import java.awt.*;
9 import java.awt.event.ActionEvent;
10
11
12 public class BoundaryFrame extends MorphFrame {
13 private Menu boundaryMenu = getMenu("Boundary");
14 private Menu countourMenu = getMenu("Countour");
15
16 private MenuItem grayPyramid_mi =
17 addMenuItem(boundaryMenu, "[E-p]grayPyramid");
18 private MenuItem diffProcess_mi =
19 addMenuItem(boundaryMenu, "[E-d]iffProcess");
20 private MenuItem drawFramePoints_mi =
21 addMenuItem(boundaryMenu, "drawFramePoints");
22 private MenuItem edge2HeightField_mi =
23 addMenuItem(boundaryMenu, "Edge->height field");
24 private MenuItem buildPoints_mi =
25 addMenuItem(boundaryMenu, "buildPoints");
26
27 private MenuItem houghDetect_mi =
28 addMenuItem(boundaryMenu, "[E-H]houghDetect");
29 private MenuItem houghDetectGray_mi =
30 addMenuItem(boundaryMenu, "houghDetectGray");
31
32 private MenuItem copyToChildFrame_mi =
33 addMenuItem(getFileMenu(), "[E-C]copyToChildFrame");
34 private MenuItem grabChild_mi =
35 addMenuItem(getFileMenu(), "[E-G]grabChild");
36
37 private MenuItem bugWalk_mi =
38 addMenuItem(countourMenu, "[b]ug walk");
39 private MenuItem printPolys_mi =
40 addMenuItem(countourMenu, "printPolys...");
41 private MenuItem listPolys_mi =
42 addMenuItem(countourMenu, "listPolys");
43 private MenuItem filterPolys_mi =
44 addMenuItem(countourMenu, "filterPolys");
45 private MenuItem drawPoly_mi =
46 addMenuItem(countourMenu, "drawPoly");
47
48 private MenuItem displayHoughOfRed_mi =
49 addMenuItem(boundaryMenu, "[E-R]displayHoughOfRed");
50 private MenuItem drawSomeBigPoints_mi =
51 addMenuItem(boundaryMenu, "[E-D]drawSomeBigPoints");
52 private MenuItem computeHoughAndDraw_mi =
53 addMenuItem(boundaryMenu, "[E-T-C]computeHoughAndDraw");
54 private MenuItem computeMagnitudeAndGradiant_mi =
55 addMenuItem(boundaryMenu, "computeMagnitudeAndGradiant");
56
57 private MenuItem houghEdge_mi =
58 addMenuItem(boundaryMenu, "[E-I]houghEdge");
59 private MenuItem inverseHoughToRed_mi =
60 addMenuItem(boundaryMenu, "Inverse Hough To Red");
61 private MenuItem singlePixelEdge_mi =
62 addMenuItem(boundaryMenu, "[E-s]inglePixelEdge");
63
64 private MenuItem print_mi = addMenuItem(getFileMenu(), "Print...");
65
66 private Polygons polyList = new Polygons();
67
68 private boolean drawOnlyPolys = false;
69
70
71 public Polygons getPolyList() {
72 return polyList;
73 }
74
75 public void setPolyList(Polygons v) {
76 polyList = v;
77 }
78
79 public void actionPerformed(ActionEvent e) {
80
81
82 if (match(e, edge2HeightField_mi)) {
83 edge2HeightField();
84 return;
85 }
86
87 if (match(e, buildPoints_mi)) {
88 buildPoints();
89 return;
90 }
91 if (match(e, drawFramePoints_mi)) {
92 drawFramePoints();
93 return;
94 }
95
96 if (match(e, diffProcess_mi)) {
97 diffProcess();
98 return;
99 }
100 if (match(e, computeMagnitudeAndGradiant_mi)) {
101 computeMagnitudeAndGradiant();
102 return;
103 }
104 if (match(e, listPolys_mi)) {
105 polyList.listPolys();
106 return;
107 }
108 if (match(e, filterPolys_mi)) {
109 filterPolys();
110 return;
111 }
112 if (match(e, printPolys_mi)) {
113 printPolys();
114 return;
115 }
116 if (match(e, houghDetectGray_mi)) {
117 houghDetect();
118 return;
119 }
120 if (match(e, grabChild_mi)) {
121 grabChild();
122 return;
123 }
124 if (match(e, houghDetect_mi)) {
125 houghDetect();
126 return;
127 }
128 if (match(e, computeHoughAndDraw_mi)) {
129 computeHoughAndDraw();
130 return;
131 }
132 if (match(e, drawSomeBigPoints_mi)) {
133 drawSomeBigPoints();
134 return;
135 }
136 if (match(e, inverseHoughToRed_mi)) {
137 inverseHoughToRed();
138 return;
139 }
140 if (match(e, copyToChildFrame_mi)) {
141 copyToChildFrame();
142 return;
143 }
144 if (match(e, houghEdge_mi)) {
145 houghEdge();
146 return;
147 }
148 if (match(e, displayHoughOfRed_mi)) {
149 displayHoughOfRed();
150 return;
151 }
152 if (match(e, grayPyramid_mi)) {
153 grayPyramid(MorphUtils.getKsquare());
154 return;
155 }
156 if (match(e, singlePixelEdge_mi)) {
157 singlePixelEdge();
158 return;
159 }
160 if (match(e, drawPoly_mi)) {
161 polyList.drawPolys(getGraphics());
162 return;
163 }
164 if (match(e, bugWalk_mi)) {
165 bugWalk();
166 return;
167 }
168 if (match(e, print_mi)) {
169 PrintContainer(this);
170 return;
171 }
172 super.actionPerformed(e);
173 }
174
175 public void drawFramePoints() {
176 String args[] = {""};
177 DrawFrame.main(args);
178 }
179
180 /**
181 edge2HeightField - input and image, output
182 x,y,z points.
183 */
184 public void edge2HeightField() {
185 int n = 1;
186 for (int x = 0; x < getImageWidth(); x++)
187 for (int y = 0; y < getImageHeight(); y++)
188 if (shortImageBean.getR()[x][y] == 255)
189 n++;
190 System.out.println("found " + n + " points");
191 float pointX[] = new float[n];
192 float pointY[] = new float[n];
193 float pointZ[] = new float[n];
194 for (int x = 0,i = 0; x < getImageWidth(); x++)
195 for (int y = 0; y < getImageHeight(); y++)
196 if (shortImageBean.getR()[x][y] == 255) {
197 pointX[i] = x / ((float) getImageWidth());
198 pointY[i] = y / ((float) getImageHeight());
199 pointZ[i] = 1f;
200 }
201 DrawFrame.drawPoints(pointX, pointY, pointZ);
202 }
203
204
205 public void grayPyramid(float k[][]) {
206 short[][] r = MorphUtils.dilategs(MorphUtils.erodegs(shortImageBean.getR(), k), k);
207 shortImageBean.setR(r);
208 short[][] r1 = MorphUtils.erodegs(MorphUtils.dilategs(shortImageBean.getR(), k), k);
209 shortImageBean.setR(r1);
210 grayResample(2);
211 short[][] r2 = trim(2, 2, shortImageBean.getR());
212 shortImageBean.setR(r2);
213 shortImageBean.copyRedToGreenAndBlue();
214 short2Image();
215 }
216
217 private double radiusTable(int x) {
218 // wrong..measure this!
219 double r0 = 1;
220 double r1 = 100;
221 double t = x / 100; //0..1?
222 return t * r1 + (1 - t) * r0;
223 }
224
225 private void buildPoints() {
226 int numberOfPoints = 100;
227 int X[] = new int[numberOfPoints];
228 int Y[] = new int[numberOfPoints];
229 int Z[] = new int[numberOfPoints];
230 double eps = (1.0 / numberOfPoints) * 2 * Math.PI;
231 int n = 0;
232 double radius;
233 loop: for (double theta = 0; theta < 2 * Math.PI; theta += eps) {
234 for (int x = 0; x < getImageWidth(); x++)
235 for (int y = 0; y < getImageHeight(); y++) {
236 if (shortImageBean.getR()[x][y] == 0) continue;
237 if (n >= numberOfPoints - 1) break loop;
238 n++;
239 radius = radiusTable(x);
240 X[n] = (int)
241 ((Math.sin(theta) * radius) - 256 / 2);
242 Y[n] = y;
243 Z[n] = (int) radius;
244 }
245 //stepMotorAndDigitize...
246 //diffProcess();
247 // send me an e-mail if you
248 // want to do this....
249 // I have serial-port
250 // and video digitization
251 // drivers in java...
252 // This is used for 3D scanners!!
253 // Doug Lyon
254 // lyon@DocJava.com
255 }
256 DrawFrame f = new DrawFrame("DrawFrame");
257 f.setSize(256, 256);
258 f.show();
259 f.setUpFrame();
260 f.setPoints(X, Y, Z);
261 f.addFocusListener(f);
262 f.repaint();
263 }
264
265 /**
266 * Process a structured illumination based
267 * multi-order diffraction subimage.
268 * A turntable is used to rotate the object
269 * to be digitized.
270 */
271 private void diffProcess() {
272 int x1 = 145;
273 int y1 = 18;
274 int x2 = 215;
275 int y2 = 245;
276 short threshValue = 106;
277 setImageWidth(x2 - x1);
278 setImageHeight(y2 - y1);
279 NegateFrame nf = subFrame(x1, y1, getImageWidth(), getImageHeight());
280 short[][] r = Mat2.copyArray(shortImageBean.getR());
281 shortImageBean.setR(r);
282 nf.setVisible(false);
283 System.out.println("Copy red to green and blue");
284 int width1 = getImageWidth() - 1;
285 setImageWidth(width1);
286 int height1 = getImageHeight() - 1;
287 setImageHeight(height1);
288 shortImageBean.copyRedToGreenAndBlue();
289 setSize(getImageWidth(), getImageHeight());
290 lp3();
291 Mat2.threshold(shortImageBean.getR(), threshValue);
292 Mat2.threshold(shortImageBean.getG(), threshValue);
293 Mat2.threshold(shortImageBean.getB(), threshValue);
294 skeleton();
295 medianSquare2x2();
296 medianSquare2x2();
297 skeleton();
298 thresh();
299 wellConditioned();
300 short2Image();
301
302 }
303
304 private double cos(double alpha) {
305 return
306 Math.cos(alpha * Math.PI / 180);
307 }
308
309 private double sin(double alpha) {
310 return
311 Math.sin(alpha * Math.PI / 180);
312 }
313
314 private int atan(int y, int x) {
315 return (int)
316 (180 * Math.atan2(y, x) / Math.PI);
317 }
318
319 //BoundaryFrame child = null;
320 public void copyToChildFrame() {
321 short _r[][] = new short[getImageWidth()][getImageHeight()];
322 short _g[][] = new short[getImageWidth()][getImageHeight()];
323 short _b[][] = new short[getImageWidth()][getImageHeight()];
324 for (int x = 0; x < getImageWidth(); x++)
325 for (int y = 0; y < getImageHeight(); y++) {
326 _r[x][y] = shortImageBean.getR()[x][y];
327 _g[x][y] = shortImageBean.getG()[x][y];
328 _b[x][y] = shortImageBean.getB()[x][y];
329 }
330 child = new TopFrame(
331 "copy of BoundaryFrame",
332 _r, _g, _b);
333 child.setSize(getImageWidth(), getImageHeight());
334 }
335
336 public BoundaryFrame(String title) {
337 super(title);
338 boundaryMenu.add(countourMenu);
339 getSpatialFilterMenu().add(boundaryMenu);
340 }
341
342 private int rhoStep = 1;
343 private int thetaStep = 1;
344
345 public void displayHoughOfRed() {
346 short[][] r = hough();
347 shortImageBean.setR(r);
348 setImageWidth(shortImageBean.getR().length);
349 setImageHeight(shortImageBean.getR()[0].length);
350 setSize(getImageWidth(), getImageHeight());
351 shortImageBean.copyRedToGreenAndBlue();
352 short2Image();
353 show();
354 }
355
356 private Point identifyLargestPoint() {
357 int max = -1;
358 Point p = null;
359 for (int x = 0; x < getImageWidth(); x++)
360 for (int y = 0; y < getImageHeight(); y++) {
361 if (shortImageBean.getG()[x][y] > max) {
362 max = shortImageBean.getG()[x][y];
363 p = new Point(x, y);
364 }
365 }
366 return p;
367 }
368
369 public Point[] getTheLargestPoints(int n) {
370 Point points[] = new Point[n];
371 for (int i = 0; i < n; i++) {
372 Point p = identifyLargestPoint();
373 points[i] = p;
374 if (p == null) break;
375 shortImageBean.getG()[p.x][p.y] = 0;
376 }
377 return points;
378 }
379
380 public void drawSomeBigPoints() {
381 Point points[] = getTheLargestPoints(4);
382 drawThePoints(points);
383 drawHoughLines(points);
384 }
385
386 public TopFrame child = null;
387
388 public void computeHoughAndDraw() {
389
390 copyToChildFrame();
391 child.displayHoughOfRed();
392 Point points[] = child.getTheLargestPoints(40);
393 child.linearTransform();
394 drawHoughLines(points);
395 drawThePoints(points);
396 shortImageBean.copyRedToGreenAndBlue();
397 short2Image();
398 }
399
400
401 public void andWithChild() {
402 if (child == null) return;
403 for (int i = 0; i < getImageWidth(); i++)
404 for (int j = 0; j < getImageHeight(); j++) {
405 shortImageBean.getR()[i][j] = min(shortImageBean.getR()[i][j], shortImageBean.getR()[i][j]);
406 shortImageBean.getG()[i][j] = min(shortImageBean.getG()[i][j], shortImageBean.getG()[i][j]);
407 shortImageBean.getB()[i][j] = min(shortImageBean.getB()[i][j], shortImageBean.getB()[i][j]);
408 }
409 }
410
411 private short min(short m1, short m2) {
412 if (m1 < m2) return m1;
413 return m2;
414 }
415
416 public void drawThePoints(Point points[]) {
417 Graphics g = getGraphics();
418 g.setColor(Color.white);
419 int n = points.length;
420 for (int i = 0; i < n; i++) {
421 Point p = points[i];
422 g.drawOval(p.x - 5, p.y - 5, 10, 10);
423 }
424 }
425
426 public void drawHoughLines(Point points[]) {
427 Graphics g = getGraphics();
428 g.setColor(Color.white);
429 for (int i = 0; i < points.length; i++) {
430 Point p = points[i];
431 int rho = p.x;
432 int theta = p.y;
433 int x1 = 0;
434 int x2 = getImageWidth();
435 int y1 = (int) ((rho - cos(theta) * x1) / sin(theta));
436 int y2 = (int) ((rho - cos(theta) * x2) / sin(theta));
437
438 if (theta == 0) {
439 x1 = rho;
440 x2 = rho;
441 y1 = 0;
442 y2 = getImageHeight();
443 }
444 drawLineRed(x1, y1, x2, y2);
445 g.drawLine(x1, y1, x2, y2);
446 }
447 }
448
449 public short[][] hough() {
450 int thetaMax = 360;
451 int radiusMax = (int) Math.sqrt(getImageWidth() * getImageWidth() + getImageHeight() * getImageHeight());
452 short s[][] = new short[radiusMax][thetaMax];
453 for (int x = 0; x < shortImageBean.getR().length; x++) {
454 for (int y = 0; y < shortImageBean.getR()[0].length; y++) {
455 if (shortImageBean.getR()[x][y] == 0) continue;
456 drawHoughLine(x, y, s);
457 }
458 }
459 return s;
460 }
461
462 public short[][] houghGray2() {
463 int thetaMax = 360;
464 int radiusMax = (int) Math.sqrt(getImageWidth() * getImageWidth() + getImageHeight() * getImageHeight());
465 short s[][] = new short[radiusMax][thetaMax];
466 for (int x = 0; x < shortImageBean.getR().length; x++) {
467 for (int y = 0; y < shortImageBean.getR()[0].length; y++) {
468 if (shortImageBean.getR()[x][y] == 0) continue;
469 drawHoughLineGray(x, y, s);
470 }
471 }
472 return s;
473 }
474
475 public void drawHoughLine(int x, int y,
476 short s[][]) {
477 for (int theta = 0; theta < s[0].length; theta++) {
478 int rho = (int) (x * cos(theta) + y * sin(theta));
479 if (rho >= s.length) continue;
480 if (rho < 0) continue;
481 s[rho][theta]++;
482 }
483 }
484
485 public void drawHoughLineGray(int x, int y,
486 short s[][]) {
487 int theta = atan(shortImageBean.getG()[x][y], shortImageBean.getB()[x][y]);
488 if (theta < 0) return;
489 if (theta > s[0].length) return;
490 int rho = (int) (x * cos(theta) + y * sin(theta));
491 if (rho >= s.length) return;
492 if (rho < 0) return;
493 s[rho][theta]++;
494 }
495
496 public void houghEdge() {
497 copyToChildFrame();
498 child.displayHoughOfRed();
499 child.unahe();
500 child.copyToChildFrame();
501 child.child.thresh();
502 andHough(child.child);
503 short2Image();
504 }
505
506 public void houghDetect() {
507 copyToChildFrame();
508 child.displayHoughOfRed();
509 inverseHough();
510 }
511
512 public void andHough(BoundaryFrame bf) {
513 System.out.println("hough computing");
514
515 for (int x = 0; x < shortImageBean.getR().length; x++)
516 for (int y = 0; y < shortImageBean.getR()[0].length; y++) {
517 if (shortImageBean.getR()[x][y] == 0) continue;
518 int theta = atan(y, x);
519 if (theta < 0) continue;
520 if (theta >= 360) continue;
521 int rho = (int) (x * cos(theta) + y * sin(theta));
522 if (rho >= getImageWidth()) continue;
523 if (rho < 0) continue;
524 if (shortImageBean.getR()[rho][theta] == 0)
525 shortImageBean.getR()[x][y] = 0;
526 }
527 }
528
529
530 public void inverseHoughToRed() {
531 inverseHoughToRed(rhoStep, thetaStep);
532 shortImageBean.copyRedToGreenAndBlue();
533 short2Image();
534 }
535
536 public void inverseHough() {
537 Point points[] = child.getTheLargestPoints(10);
538 child.linearTransform();
539 copyToChildFrame();
540 child.reinitializeRedGreenAndBlue();
541 System.out.println("About to draw hough lines");
542 child.drawHoughLines(points);
543 System.out.println("Anding with child");
544 andWithChild();
545 shortImageBean.copyRedToGreenAndBlue();
546 short2Image();
547 show();
548 }
549
550 private void inverseHoughToRed(int rhoStep, int thetaStep) {
551 for (int hx = 0; hx < shortImageBean.getG().length; hx++)
552 for (int hy = 0; hy < shortImageBean.getG()[0].length; hy++) {
553 if (shortImageBean.getG()[hx][hy] == 0) continue;
554 int x1 = 0;
555 int x2 = getImageWidth() - 1;
556 int theta = hy * thetaStep;
557 int rho = hx * rhoStep;
558 double cosTheta = cos(theta);
559 double sinTheta = sin(theta);
560 int y1 = clip((rho - x1 * cosTheta) / sinTheta);
561 int y2 = clip((rho - x2 * cosTheta) / sinTheta);
562 drawLineRed(x1, y1, x2, y2);
563 }
564 }
565
566
567 public void drawLineRed2(int x1, int y1, int x2, int y2) {
568 double dx = Math.abs(x1 - x2);
569 double dy = Math.abs(y1 - y2);
570 double length = 2 * Math.sqrt(dx * dx + dy * dy);
571 double eps = 1 / length;
572 for (double t = 0; t < 1; t = t + eps) {
573 int x = (int) ((1 - t) * x1 + t * x2);
574 int y = (int) ((1 - t) * y1 + t * y2);
575 if (x >= getImageWidth()) continue;
576 if (y >= getImageHeight()) continue;
577 if (x < 0) continue;
578 if (y < 0) continue;
579
580 shortImageBean.getR()[x][y] = 255;
581 }
582 }
583
584 private int sign(int x) {
585 if (x == 0) return 0;
586 if (x < 0) return -1;
587 return 1;
588 }
589
590 public void grabChild() {
591 MorphFrame child = (MorphFrame) super.child;
592 if (child == null) {
593 System.out.println("Child is null");
594 return;
595 }
596 int width1 = getImageWidth();
597 setImageWidth(width1);
598 int height1 = getImageHeight();
599 setImageHeight(height1);
600 short[][] r = shortImageBean.getR();
601 shortImageBean.setR(r);
602 setG(shortImageBean.getG());
603 setB(shortImageBean.getB());
604 short2Image();
605 }
606
607 // Bresenham's Algorithm;
608 // Adapted from Newman and Sproull,
609 // "Principles of Interactive Computer Graphics"
610 // and
611 // Graphics Gems Vol. 1, pp 99 by
612 // Paul S. Heckbert.
613 public void drawLineRed(int x1, int y1, int x2, int y2) {
614 int deltaX = x2 - x1;
615 int deltaY = y2 - y1;
616 int absDeltaX = Math.abs(deltaX);
617 int absDeltaY = Math.abs(deltaY);
618 int absDeltaX2 = absDeltaX * 2;
619 int absDeltaY2 = absDeltaY * 2;
620 int sx = sign(deltaX);
621 int sy = sign(deltaY);
622
623 int x = x1;
624 int y = y1;
625 // e is the error
626 int e = 0;
627
628 if (absDeltaX2 > absDeltaY2) {
629 e = absDeltaY2 - absDeltaX;
630 while (true) {
631 setPel(x, y);
632 if (x == x2) return;
633 if (e >= 0) {
634 y += sy;
635 e -= absDeltaX2;
636 }
637 x += sx;
638 e += absDeltaY2;
639 }
640 }
641 e = absDeltaX2 - absDeltaY;
642 while (true) {
643 setPel(x, y);
644 if (y == y2) return;
645 if (e >= 0) {
646 x += sx;
647 e -= absDeltaY2;
648 }
649 y += sy;
650 e += absDeltaX2;
651 }
652 }
653
654 private void setPel(int x, int y) {
655 if (x < 0) return;
656 if (x >= shortImageBean.getR().length) return;
657 if (y < 0) return;
658 if (y >= shortImageBean.getR()[0].length) return;
659 shortImageBean.getR()[x][y] = 255;
660 shortImageBean.getG()[x][y] = 255;
661 shortImageBean.getB()[x][y] = 255;
662 }
663
664 public void testDrawLineRed() {
665 reinitializeRedGreenAndBlue();
666 drawLineRed(0, 0, getImageWidth(), getImageHeight());
667 drawLineRed(getImageWidth(), 0, 0, getImageHeight());
668 drawLineRed(getImageWidth() / 2, getImageHeight() / 2, 0, getImageHeight() / 2);
669 shortImageBean.copyRedToGreenAndBlue();
670 short2Image();
671 }
672
673 private int clip(double y) {
674 if (y > getImageHeight()) return getImageHeight() - 1;
675 if (y < 0) return 0;
676 return (int) y;
677 }
678
679 public short[][] trim(int dx, int dy, short s[][]) {
680 int nw = s.length - 2 * dx;
681 int nh = s[0].length - 2 * dy;
682 short ns[][] = new short[nw][nh];
683 for (int x = dx; x < getImageWidth() - dx; x++)
684 for (int y = dy; y < getImageHeight() - dy; y++)
685 ns[x - dx][y - dy] = s[x][y];
686 setImageWidth(nw);
687 setImageHeight(nh);
688 return ns;
689 }
690
691 private void grayResample(int ratio) {
692 int width1 = getImageWidth() / ratio;
693 setImageWidth(width1);
694 int height1 = getImageHeight() / ratio;
695 setImageHeight(height1);
696 short[][] r = Mat2.resample(shortImageBean.getR(), ratio);
697 shortImageBean.setR(r);
698 }
699
700
701 public static void PrintContainer(Container c) {
702 Toolkit tk = Toolkit.getDefaultToolkit();
703 PrintJob printJob =
704 tk.getPrintJob(
705 (Frame) c,
706 "print me!",
707 null);
708 Graphics g = printJob.getGraphics();
709 c.paint(g);
710 printJob.end();
711 }
712
713
714 public static void main(String args[]) {
715 BoundaryFrame bf = new BoundaryFrame("BoundaryFrame");
716 bf.testDrawLineRed();
717 }
718
719 /**
720 * make new instances of the internal short arrays.
721 */
722
723 public void reinitializeRedGreenAndBlue() {
724 short[][] r = new short[getImageWidth()][getImageHeight()];
725 shortImageBean.setR(r);
726 setG(new short[getImageWidth()][getImageHeight()]);
727 setB(new short[getImageWidth()][getImageHeight()]);
728 }
729
730
731 private int pointCount() {
732 int i = 0;
733 for (int x = 0; x < getImageWidth(); x++)
734 for (int y = 0; y < getImageHeight(); y++) if (shortImageBean.getR()[x][y] != 0) i++;
735 return i;
736 }
737
738 private void computeMagnitudeAndGradiant() {
739 for (int x = 1; x < getImageWidth() - 1; x++)
740 for (int y = 1; y < getImageHeight() - 1; y++)
741 computeGradient(x, y);
742 for (int x = 1; x < getImageWidth() - 1; x++)
743 for (int y = 1; y < getImageHeight() - 1; y++)
744 shortImageBean.getR()[x][y] = (short) Math.sqrt(
745 shortImageBean.getG()[x][y] * shortImageBean.getG()[x][y] + shortImageBean.getB()[x][y] * shortImageBean.getB()[x][y]);
746 short2Image();
747 }
748 // abc
749 // hid
750 // gfe
751 private void computeGradient(int x, int y) {
752 int a1, b1, c1, d1, e1, f1, h1, g1;
753 a1 = shortImageBean.getR()[x - 1][y + 1];
754 b1 = shortImageBean.getR()[x][y + 1];
755 c1 = shortImageBean.getR()[x + 1][y + 1];
756 d1 = shortImageBean.getR()[x + 1][y];
757 e1 = shortImageBean.getR()[x + 1][y - 1];
758 f1 = shortImageBean.getR()[x][y - 1];
759 g1 = shortImageBean.getR()[x - 1][y - 1];
760 h1 = shortImageBean.getR()[x - 1][y];
761
762 shortImageBean.getG()[x][y] = (short) ((c1 - g1) + (e1 - a1) + 2 * (d1 - h1));
763 shortImageBean.getB()[x][y] = (short) ((c1 - g1) + (a1 - e1) + 2 * (b1 - f1));
764 }
765
766
767 private void singlePixelEdge() {
768 colorPyramid(MorphUtils.getKsquare());
769 show();
770 thresh();
771 outsideContour(MorphUtils.getKcross());
772 }
773
774 public void bugWalk() {
775 polyList = new Polygons();
776 System.out.println("number of points = " + pointCount());
777 Timer t = new Timer();
778 t.start();
779 for (int x = 1; x < getImageWidth() - 1; x++)
780 for (int y = 1; y < getImageHeight() - 1; y++)
781 if (shortImageBean.getR()[x][y] != 0)
782 buildPolygonList(x, y);
783 t.print("poly done!");
784 polyList.polyStats();
785 filterPolys();
786 }
787
788
789 private void buildPolygonList(int x, int y) {
790 Polygon p = new Polygon();
791 p.addPoint(x, y);
792 shortImageBean.getR()[x][y] = 0;
793 if (shortImageBean.getR()[x + 1][y] != 0) {
794 buildPolygonList(x + 1, y, p);
795 polyList.addElement(p);
796 return;
797 }
798 if (shortImageBean.getR()[x + 1][y + 1] != 0) {
799 buildPolygonList(x + 1, y + 1, p);
800 polyList.addElement(p);
801 return;
802 }
803 if (shortImageBean.getR()[x][y + 1] != 0) {
804 buildPolygonList(x, y + 1, p);
805 polyList.addElement(p);
806 return;
807 }
808
809 }
810
811 private void buildPolygonList(int x, int y, Polygon p) {
812 p.addPoint(x, y);
813 shortImageBean.getR()[x][y] = 0;
814 try {
815 if (shortImageBean.getR()[x + 1][y] != 0) {
816 buildPolygonList(x + 1, y, p);
817 return;
818 }
819 if (shortImageBean.getR()[x + 1][y + 1] != 0) {
820 buildPolygonList(x + 1, y + 1, p);
821 return;
822 }
823 if (shortImageBean.getR()[x][y + 1] != 0) {
824 buildPolygonList(x, y + 1, p);
825 return;
826 }
827 } catch (Exception e) {
828 }
829 ;
830 }
831
832 public void printPolys() {
833 Toolkit tk = Toolkit.getDefaultToolkit();
834 PrintJob printJob =
835 tk.getPrintJob(
836 new Frame(),
837 "print me!",
838 null);
839 Graphics g = printJob.getGraphics();
840 Polygon p;
841 for (int i = 0; i < polyList.size(); i++) {
842 p = polyList.elementAt(i);
843 g.drawPolyline(p.xpoints, p.ypoints, p.npoints);
844 }
845 printJob.end();
846 }
847
848 public void filterPolys() {
849 Timer t = new Timer();
850 t.start();
851 Polygon p = polyList.elementAt(0);
852 Polygon pp;
853 Polygons newPolys = new Polygons();
854 newPolys.addElement(p);
855 polyList.removeElementAt(0);
856 while (polyList.size() > 0) {
857 int i = nextClosestPoly(p);
858 pp = polyList.elementAt(i);
859 polyList.removeElementAt(i);
860 pp = thinPoly(pp); // implement this for hw!
861 //if (combinePolys(p,pp)) continue;
862
863 newPolys.addElement(pp);
864 }
865 polyList = newPolys;
866 t.print("Polys ordered");
867 polyList.polyStats();
868 polyList.drawPolys(getGraphics());
869 //listPolys(polyList);
870 }
871
872 // here is the basic idea...thin poly
873 // can you order the polys?
874 public Polygon thinPoly(Polygon p) {
875 if (p.npoints <= 2) return p;
876 Polygon pp = new Polygon();
877 int x0 = p.xpoints[0];
878 int y0 = p.ypoints[0];
879 int x1 = p.ypoints[1];
880 int y1 = p.ypoints[1];
881 pp.addPoint(x0, y0);
882 for (int i = 1; i < p.npoints - 1; i++) {
883 int xi = p.xpoints[i];
884 int yi = p.ypoints[i];
885 if (onLine(x0, y0, x1, y1, xi, yi) && nextTo(x1, y1, xi, yi)) {
886 //System.out.println("onLine:\n"
887 // +x0+","+y0+","+x1+","+y1+","+xi+","+yi);
888 x1 = xi;
889 y1 = yi;
890 continue;
891 }
892 pp.addPoint(p.xpoints[i - 1], p.ypoints[i - 1]);
893 x0 = p.xpoints[i - 1];
894 y0 = p.ypoints[i - 1];
895 x1 = xi;
896 y1 = yi;
897 }
898 pp.addPoint(p.xpoints[p.npoints - 1], p.ypoints[p.npoints - 1]);
899 return pp;
900 }
901
902 private boolean nextTo(
903 int x0, int y0,
904 int x1, int y1) {
905 int dx = x1 - x0;
906 int dy = y1 - y0;
907 return Math.sqrt(dx * dx + dy * dy) < 2;
908 }
909
910 public boolean onLine(
911 int x0, int y0,
912 int x1, int y1,
913 int x2, int y2) {
914 int dx = x1 - x0;
915 int dy = y1 - y0;
916 int dx2 = x2 - x0;
917 int dy2 = y2 - y0;
918 return Math.abs(dy * dx2 - dy2 * dx) <
919 max(Math.abs(dx), Math.abs(dy));
920 }
921
922 private double max(int x, int y) {
923 if (x > y) return x;
924 return y;
925 }
926
927 public int nextClosestPoly(Polygon p) {
928 double dMin = 10000;
929 int next = 0;
930 for (int i = 0; i < polyList.size(); i++) {
931 Polygon pp = polyList.elementAt(i);
932 if (distance(p, pp) < dMin) {
933 dMin = distance(p, pp);
934 next = i;
935 }
936 }
937 return next;
938 }
939
940 public boolean combinePolys(Polygon p1, Polygon p2) {
941 if (distance(p1, p2) < 2) {
942 for (int i = 0; i < p2.npoints; i++)
943 p1.addPoint(p2.xpoints[i], p2.ypoints[i]);
944 return true;
945 }
946 return false;
947 }
948
949 public double distance(Polygon p1, Polygon p2) {
950 double x1 = p1.xpoints[p1.npoints - 1];
951 double y1 = p1.ypoints[p1.npoints - 1];
952 double x2 = p2.xpoints[0];
953 double y2 = p2.ypoints[0];
954 double dx = x1 - x2;
955 double dy = y1 - y2;
956 return Math.sqrt(dx * dx + dy * dy);
957 }
958
959 public Menu getBoundaryMenu() {
960 return boundaryMenu;
961 }
962
963 public void setBoundaryMenu(Menu boundaryMenu) {
964 this.boundaryMenu = boundaryMenu;
965 }
966
967 public Menu getCountourMenu() {
968 return countourMenu;
969 }
970
971 public void setCountourMenu(Menu countourMenu) {
972 this.countourMenu = countourMenu;
973 }
974
975 public MenuItem getGrayPyramid_mi() {
976 return grayPyramid_mi;
977 }
978
979 public void setGrayPyramid_mi(MenuItem grayPyramid_mi) {
980 this.grayPyramid_mi = grayPyramid_mi;
981 }
982
983 public MenuItem getDiffProcess_mi() {
984 return diffProcess_mi;
985 }
986
987 public void setDiffProcess_mi(MenuItem diffProcess_mi) {
988 this.diffProcess_mi = diffProcess_mi;
989 }
990
991 public MenuItem getDrawFramePoints_mi() {
992 return drawFramePoints_mi;
993 }
994
995 public void setDrawFramePoints_mi(MenuItem drawFramePoints_mi) {
996 this.drawFramePoints_mi = drawFramePoints_mi;
997 }
998
999 public MenuItem getEdge2HeightField_mi() {
1000 return edge2HeightField_mi;
1001 }
1002
1003 public void setEdge2HeightField_mi(MenuItem edge2HeightField_mi) {
1004 this.edge2HeightField_mi = edge2HeightField_mi;
1005 }
1006
1007 public MenuItem getBuildPoints_mi() {
1008 return buildPoints_mi;
1009 }
1010
1011 public void setBuildPoints_mi(MenuItem buildPoints_mi) {
1012 this.buildPoints_mi = buildPoints_mi;
1013 }
1014
1015 public MenuItem getHoughDetect_mi() {
1016 return houghDetect_mi;
1017 }
1018
1019 public void setHoughDetect_mi(MenuItem houghDetect_mi) {
1020 this.houghDetect_mi = houghDetect_mi;
1021 }
1022
1023 public MenuItem getHoughDetectGray_mi() {
1024 return houghDetectGray_mi;
1025 }
1026
1027 public void setHoughDetectGray_mi(MenuItem houghDetectGray_mi) {
1028 this.houghDetectGray_mi = houghDetectGray_mi;
1029 }
1030
1031 public MenuItem getCopyToChildFrame_mi() {
1032 return copyToChildFrame_mi;
1033 }
1034
1035 public void setCopyToChildFrame_mi(MenuItem copyToChildFrame_mi) {
1036 this.copyToChildFrame_mi = copyToChildFrame_mi;
1037 }
1038
1039 public MenuItem getGrabChild_mi() {
1040 return grabChild_mi;
1041 }
1042
1043 public void setGrabChild_mi(MenuItem grabChild_mi) {
1044 this.grabChild_mi = grabChild_mi;
1045 }
1046
1047 public MenuItem getBugWalk_mi() {
1048 return bugWalk_mi;
1049 }
1050
1051 public void setBugWalk_mi(MenuItem bugWalk_mi) {
1052 this.bugWalk_mi = bugWalk_mi;
1053 }
1054
1055 public MenuItem getPrintPolys_mi() {
1056 return printPolys_mi;
1057 }
1058
1059 public void setPrintPolys_mi(MenuItem printPolys_mi) {
1060 this.printPolys_mi = printPolys_mi;
1061 }
1062
1063 public MenuItem getListPolys_mi() {
1064 return listPolys_mi;
1065 }
1066
1067 public void setListPolys_mi(MenuItem listPolys_mi) {
1068 this.listPolys_mi = listPolys_mi;
1069 }
1070
1071 public MenuItem getFilterPolys_mi() {
1072 return filterPolys_mi;
1073 }
1074
1075 public void setFilterPolys_mi(MenuItem filterPolys_mi) {
1076 this.filterPolys_mi = filterPolys_mi;
1077 }
1078
1079 public MenuItem getDrawPoly_mi() {
1080 return drawPoly_mi;
1081 }
1082
1083 public void setDrawPoly_mi(MenuItem drawPoly_mi) {
1084 this.drawPoly_mi = drawPoly_mi;
1085 }
1086
1087 public MenuItem getDisplayHoughOfRed_mi() {
1088 return displayHoughOfRed_mi;
1089 }
1090
1091 public void setDisplayHoughOfRed_mi(MenuItem displayHoughOfRed_mi) {
1092 this.displayHoughOfRed_mi = displayHoughOfRed_mi;
1093 }
1094
1095 public MenuItem getDrawSomeBigPoints_mi() {
1096 return drawSomeBigPoints_mi;
1097 }
1098
1099 public void setDrawSomeBigPoints_mi(MenuItem drawSomeBigPoints_mi) {
1100 this.drawSomeBigPoints_mi = drawSomeBigPoints_mi;
1101 }
1102
1103 public MenuItem getComputeHoughAndDraw_mi() {
1104 return computeHoughAndDraw_mi;
1105 }
1106
1107 public void setComputeHoughAndDraw_mi(MenuItem computeHoughAndDraw_mi) {
1108 this.computeHoughAndDraw_mi = computeHoughAndDraw_mi;
1109 }
1110
1111 public MenuItem getComputeMagnitudeAndGradiant_mi() {
1112 return computeMagnitudeAndGradiant_mi;
1113 }
1114
1115 public void setComputeMagnitudeAndGradiant_mi(MenuItem computeMagnitudeAndGradiant_mi) {
1116 this.computeMagnitudeAndGradiant_mi = computeMagnitudeAndGradiant_mi;
1117 }
1118
1119 public MenuItem getHoughEdge_mi() {
1120 return houghEdge_mi;
1121 }
1122
1123 public void setHoughEdge_mi(MenuItem houghEdge_mi) {
1124 this.houghEdge_mi = houghEdge_mi;
1125 }
1126
1127 public MenuItem getInverseHoughToRed_mi() {
1128 return inverseHoughToRed_mi;
1129 }
1130
1131 public void setInverseHoughToRed_mi(MenuItem inverseHoughToRed_mi) {
1132 this.inverseHoughToRed_mi = inverseHoughToRed_mi;
1133 }
1134
1135 public MenuItem getSinglePixelEdge_mi() {
1136 return singlePixelEdge_mi;
1137 }
1138
1139 public void setSinglePixelEdge_mi(MenuItem singlePixelEdge_mi) {
1140 this.singlePixelEdge_mi = singlePixelEdge_mi;
1141 }
1142
1143 public MenuItem getPrint_mi() {
1144 return print_mi;
1145 }
1146
1147 public void setPrint_mi(MenuItem print_mi) {
1148 this.print_mi = print_mi;
1149 }
1150
1151 public boolean isDrawOnlyPolys() {
1152 return drawOnlyPolys;
1153 }
1154
1155 public void setDrawOnlyPolys(boolean drawOnlyPolys) {
1156 this.drawOnlyPolys = drawOnlyPolys;
1157 }
1158
1159 public int getRhoStep() {
1160 return rhoStep;
1161 }
1162
1163 public void setRhoStep(int rhoStep) {
1164 this.rhoStep = rhoStep;
1165 }
1166
1167 public int getThetaStep() {
1168 return thetaStep;
1169 }
1170
1171 public void setThetaStep(int thetaStep) {
1172 this.thetaStep = thetaStep;
1173 }
1174
1175 public TopFrame getChild() {
1176 return child;
1177 }
1178
1179 public void setChild(TopFrame child) {
1180 this.child = child;
1181 }
1182
1183
1184 }