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