/Users/lyon/j4p/src/ip/gui/frames/MartelliFrame.java

1    package ip.gui.frames; 
2     
3    import gui.run.RunButton; 
4    import j2d.edge.gabor.FilterCanvas; 
5    import j2d.edge.gabor.GaborPanel; 
6    import j2d.edge.gabor.MartelliView; 
7    import ip.gui.EdgeElement; 
8    import ip.martelli.EdgeElements; 
9    import ip.martelli.MartelliParams; 
10   import ip.transforms.GeometryUtils; 
11   import ip.transforms.Points; 
12   import ip.transforms.Polygons; 
13   import j2d.ShortImageBean; 
14   import utils.Timer; 
15    
16   import java.awt.*; 
17   import java.awt.event.ActionEvent; 
18    
19   public class MartelliFrame extends PaintFrame { 
20       private EdgeElements finalEdgeList = new EdgeElements(); 
21       // a list of all edges 
22       //private EdgeElements expandedEdgeElements = new EdgeElements(); 
23    
24    
25       //Point Begin; 
26       //Point End; 
27    
28       private MartelliParams mp = new MartelliParams(); 
29    
30    
31       private Timer t = new Timer(); 
32    
33       public void erase() { 
34           super.eraseShapes(); 
35           finalEdgeList = new EdgeElements(); 
36           setPolyList(new Polygons()); 
37           initialize(); 
38       } 
39    
40    
41       private Menu heuristicMenu = getMenu("heuristics"); 
42       private MenuItem processUserPoints_mi = 
43               addMenuItem(heuristicMenu, "[E-M]process user points"); 
44       private MenuItem erase_mi = 
45               addMenuItem(heuristicMenu, "erase path"); 
46       private MenuItem negativeRobertsOnGreen_mi = 
47               addMenuItem(heuristicMenu, "use NegativeRobertsOnGreen"); 
48       private MenuItem averageWithChild_mi = 
49               addMenuItem(getFileMenu(), "averageWithChild"); 
50    
51       private MenuItem printPath_mi = addMenuItem(heuristicMenu, "printPath"); 
52       private MenuItem gabor_mi = addMenuItem(heuristicMenu, "Gabor..."); 
53       private MenuItem grabGabor_mi = addMenuItem(heuristicMenu, "grab gabor"); 
54    
55       private GaborPanel gp = null; 
56    
57   // Inputs the green plane and outputs edges found on the 
58   // red plane. The red plane is cleared upon initialization. 
59    
60       public MartelliFrame(String title) { 
61           super(title); 
62           getBoundaryMenu().add(heuristicMenu); 
63       } 
64    
65       public static void main(String args[]) { 
66           MartelliFrame xf = new MartelliFrame("MartelliFrame"); 
67       } 
68    
69    
70       public void averageWithChild() { 
71           ShortImageBean csib = child.getShortImageBean(); 
72           shortImageBean.average(csib); 
73           short2Image(); 
74       } 
75    
76    
77       public void negativeRobertsOnGreen() { 
78           int p[] = new int[4]; 
79           float delta_u = 0; 
80           float delta_v = 0; 
81           for (int x = 0; x < getImageWidth() - 1; x++) 
82               for (int y = 0; y < getImageHeight() - 1; y++) { 
83                   p[0] = shortImageBean.getR()[x][y]; 
84                   p[1] = shortImageBean.getR()[x + 1][y]; 
85                   p[2] = shortImageBean.getR()[x][y + 1]; 
86                   p[3] = shortImageBean.getR()[x + 1][y + 1]; 
87                   delta_u = p[0] - p[3]; 
88                   delta_v = p[1] - p[2]; 
89                   shortImageBean.getG()[x][y] = 
90                           (short) (255 - Math.sqrt(delta_u * delta_u + delta_v * delta_v)); 
91               } 
92       } 
93    
94       public static int clip(int x) { 
95           if (x < 0) return 0; 
96           return x; 
97       } 
98    
99       //evaluates whether Martelli should stop searching or not 
100      private boolean terminateSearch(EdgeElement el, Point nextPoint) { 
101          //if (edges.size() > maximumNumberOfEdges ) return true; 
102          if (t.getElapsedTime() > MartelliParams.runTimeInSeconds) { 
103              t.start(); // restart timer 
104              return true; 
105          } 
106          if (el.distance(nextPoint) < 2) { 
107              t.start(); // restart timer 
108              return true; 
109          } 
110          return false; 
111      } 
112   
113   
114  // Finds out whether the current edge coordinates 
115  // have been visited 
116      EdgeElement getMarked(EdgeElement inputEdgeElement) { 
117          for (int i = 0; i < finalEdgeList.getSize(); i++) { 
118              EdgeElement el = finalEdgeList.getElementAt(i); 
119              if ((el.p1.x == inputEdgeElement.p1.x) && 
120                      (el.p1.y == inputEdgeElement.p1.y) && 
121                      (el.p2.x == inputEdgeElement.p2.x) && 
122                      (el.p2.y == inputEdgeElement.p2.y)) { 
123                  return el; 
124              } 
125          } 
126          return null; 
127      } 
128   
129  //The cost of an edge element 
130      private int C22(EdgeElement e, Point nextPoint) { 
131          int pc = 0; 
132          EdgeElement p = e.getParent(); 
133          int d = e.distance(nextPoint); 
134          if (p != null) ;//pc = p.getCost()/e.getPly(); 
135          return 
136                  clip(pc + 
137                  d + //MaxI 
138                  -( 
139                  shortImageBean.getG()[e.p1.x][e.p1.y] - 
140                  shortImageBean.getG()[e.p2.x][e.p2.y]) 
141                  ); 
142      } 
143   
144      FilterCanvas subBands[]; 
145   
146      /** 
147       *  getSubBand inputs a point and selects the correct subband direction 
148       */ 
149   
150      int getMinSubBand(Point p) { 
151          int subBand = 0; 
152          int maxValue = Integer.MIN_VALUE; 
153          int i; 
154          for (i = 1; i < subBands.length; i++) { 
155              int v = subBands[i].getGreenValueAt(p); 
156              if (v > maxValue) { 
157                  maxValue = v; 
158                  subBand = i; 
159              } 
160          } 
161          return subBand; 
162      } 
163   
164      int getMaxSubBand(Point p) { 
165          int subBand = 0; 
166          int minValue = Integer.MAX_VALUE; 
167          int i; 
168          for (i = 1; i < subBands.length; i++) { 
169              int v = subBands[i].getGreenValueAt(p); 
170              if (v < minValue) { 
171                  minValue = v; 
172                  subBand = i; 
173              } 
174          } 
175          return subBand; 
176      } 
177   
178      /** 
179       * 
180       * 
181       *  Subbands are directional Gabor detectors that 
182       *  are selected based in the subBand parameter 
183       */ 
184      private int C(EdgeElement e, Point nextMarker, int subBand, MartelliParams mp) { 
185          Point edgeEndPoint = e.p2; 
186          //Iterate through the subbands, selecting for lowest cost 
187          // Favor the bright, white edges. 
188          subBand = getMinSubBand(edgeEndPoint); 
189          int v = subBands[subBand].getGreenValueAt(edgeEndPoint); 
190   
191          v = v; // brighter edges yield lower cost 
192          // Favor longer edge chains 
193          int ply = -e.getPly(); 
194   
195          // The farther from the marker, the higher the cost 
196          int d = e.distance(nextMarker); 
197          //if (p != null) pc = p.getCost()-e.getPly(); 
198          return 
199                  (int) (ply * mp.getPly()) + 
200                  (int) (d * mp.getGreediness()) + 
201                  (int) (v * mp.getPixel()); 
202      } 
203   
204      /** 
205       *  C is a means to determine the cost of the present edge element. 
206       */ 
207      private int CSimple(EdgeElement e, Point nextPoint) { 
208          int pc = 0; 
209          EdgeElement p = e.getParent(); 
210          int d = 2 * e.distance(nextPoint); 
211          //if (p != null) pc = p.getCost()-e.getPly(); 
212          return 
213                  clip(pc + 
214                  d + shortImageBean.getG()[e.p1.x][e.p1.y]); 
215      } 
216   
217  //adds an edge element to the 'expanded' list, 
218  //if it is within the boundaries of the image 
219      private void addElementToExpandedList( 
220              Point p1, Point p2, 
221              EdgeElement parentEdgeElement, Point nextMarker, 
222              EdgeElements expandedEdgeElements, 
223              int subBand) { 
224          if (!Points.isRangeValid(p1, p2, new Dimension(getImageWidth(), getImageHeight()))) return; 
225   
226          EdgeElement e = new EdgeElement(); 
227          e.setCoordinates(p1, p2); 
228          e.setParent(parentEdgeElement); 
229          e.setCost(C(e, nextMarker, subBand, mp)); 
230          expandedEdgeElements.add(e); 
231   
232      } 
233   
234      public void paint(Graphics g) { 
235          super.paint(g); 
236          Polygons p = getPolyList(); 
237          if (p != null) 
238              p.drawPolys(g); 
239      } 
240   
241      private void expand(EdgeElement el, Point nextMarker, 
242                          EdgeElements expandedEdgeElements, 
243                          int subBand) { 
244          Points nextPoints = GeometryUtils.getNextPoints(el.p2, nextMarker); 
245          while (nextPoints.hasMorePoints()) { 
246              Point p = nextPoints.nextPoint(); 
247              addElementToExpandedList(el.p2, p, el, nextMarker, expandedEdgeElements, subBand); 
248   
249          } 
250   
251      } 
252   
253      private void initialize() { 
254          finalEdgeList = new EdgeElements(); 
255      } 
256   
257      private void processUserPoints(Points userPoints) { 
258          if (userPoints.getSize() < 2) { 
259              System.out.println("Select start and end point(s)"); 
260              return; 
261          } 
262          if (subBands == null) 
263              lowLevelPreProcessForMartelli(); 
264   
265          Polygons polyList = new Polygons(); 
266          setPolyList(polyList); 
267          Point startPoint = userPoints.getPointAt(0); 
268   
269          for (int i = 1; i < userPoints.getSize(); i++) { 
270              Point nextPoint = userPoints.getPointAt(i); 
271              Polygon p1 = 
272                      searchFromPoint( 
273                              new Point(startPoint.x, startPoint.y), nextPoint).getPath(); 
274              startPoint = nextPoint; 
275              polyList.addElement(p1); 
276          } 
277   
278      } 
279   
280      private void lowLevelPreProcessForMartelli() { 
281          copyToChildFrame(); 
282          //child.roberts2(); 
283   
284          getChild().gauss3(); 
285          getChild().unahe(); 
286          getChild().negate(); 
287          subBands = FilterCanvas.getSubBands(getChild().getImage(), getChild()); 
288          setVisible(true); 
289      } 
290   
291   
292  // the A* algorithm 
293      public EdgeElement searchFromPoint(Point startPoint, Point nextMarker) { 
294          initialize(); 
295          EdgeElement lowestCostEdgeElement; 
296   
297          //A* starts here 
298          EdgeElement startEdgeElement = new EdgeElement(); 
299          EdgeElements expandedEdgeElements = new EdgeElements(); 
300   
301          Point nextPoint = GeometryUtils.getNextPointOnLine(startPoint, nextMarker); 
302   
303          startEdgeElement.setCoordinates(startPoint, nextPoint); 
304          startEdgeElement.setOpen(true); 
305          finalEdgeList.add(startEdgeElement); 
306          // Select a filter band, assuming the domain expert's 
307          // markers are on a good edge. 
308          int subBand = getMaxSubBand(startPoint); 
309          System.out.println("new subband=" + subBand); 
310   
311          while ( 
312                  (lowestCostEdgeElement = finalEdgeList.getMinOpenNode()) 
313                  != null) { 
314              if (terminateSearch(lowestCostEdgeElement, nextMarker)) break; 
315   
316              lowestCostEdgeElement.setOpen(false); 
317              expand(lowestCostEdgeElement, nextMarker, expandedEdgeElements, subBand); 
318              if (expandedEdgeElements.getSize() == 0) continue; 
319              processExpandedNodes(expandedEdgeElements); 
320              //drawTracks(lowestCostEdgeElement); 
321          } 
322          lowestCostEdgeElement = finalEdgeList.getMinOpenNode(); 
323          //System.out.println("ply for lcn="+lowestCostNode.getPly()); 
324          //System.out.println("cost for lcn="+lowestCostNode.getCost()); 
325          return lowestCostEdgeElement; 
326      } // end martelli 
327   
328  // Let the user see the search gui.run... 
329  // great fun! 
330  //    private void drawTracks(EdgeElement lowestCostNode) { 
331  //        if (child == null) 
332  //            System.out.println( 
333  //                    "You need a child frame for a cost matrix"); 
334  //        Graphics g = child.getGraphics(); 
335      //       g.setColor(Color.red); 
336      //       g.setXORMode(Color.red); 
337  //        g.drawOval(lowestCostNode.p1.x - 1, lowestCostNode.p1.y - 1, 1, 1); 
338      //   } 
339   
340      private void processExpandedNodes(EdgeElements expandedEdgeElements) { 
341          for (int i = 0; i < expandedEdgeElements.getSize(); i++) { 
342              EdgeElement e = expandedEdgeElements.getElementAt(i); 
343              EdgeElement MarkedNode = getMarked(e); 
344              if (MarkedNode == null) { 
345                  finalEdgeList.add(e); 
346                  continue; 
347              } 
348              if (e.getCost() < MarkedNode.getCost()) 
349                  MarkedNode = e; 
350          } 
351      } 
352   
353   
354      public void gabor() { 
355          gp = new GaborPanel(getImage()); 
356          Frame f = new Frame(); 
357          f.setLayout(new BorderLayout()); 
358          f.add(gp, BorderLayout.CENTER); 
359          gp.init(); 
360          f.setVisible(true); 
361          f.setSize(200, 200); 
362      } 
363   
364   
365      public void grabGabor() { 
366          //copyToChildFrame(); 
367   
368          //child.roberts2(); 
369   
370          // child.gauss3(); 
371          //child.unahe(); 
372          //child.negate(); 
373          //child.gabor(); 
374          subBands = gp.getFilters(); 
375          MartelliView mv = new MartelliView(mp); 
376          RunButton rb = new RunButton("Apply") { 
377              public void run() { 
378                  processUserPoints(); 
379              } 
380          }; 
381          mv.addRunButton(rb); 
382          //super.setImageResize(gp.getGaborImage()); 
383   
384          //setImage( 
385          //       FFTImage.filter(super.getImage(),gp.getGaborImage())); 
386          //child.setImage(gp.getGaborImage()); 
387          // perform a filter op with the GaborImage. 
388          //child.fftR2(); 
389          //child.child = new TopFrame("filtered image", 
390          //            super.getImage()); 
391          //child.child.fftR2(); 
392          //child.complexMultR2(); 
393          //child.ifftR2(); 
394   
395      } 
396   
397   
398      public void actionPerformed(ActionEvent e) { 
399          if (match(e, gabor_mi)) { 
400              gabor(); 
401              return; 
402          } 
403   
404          if (match(e, grabGabor_mi)) { 
405              grabGabor(); 
406   
407              return; 
408          } 
409   
410          if (match(e, averageWithChild_mi)) { 
411              averageWithChild(); 
412              return; 
413          } 
414          if (match(e, negativeRobertsOnGreen_mi)) { 
415              negativeRobertsOnGreen(); 
416              return; 
417          } 
418          if (match(e, erase_mi)) { 
419              erase(); 
420              return; 
421          } 
422          if (match(e, processUserPoints_mi)) { 
423              processUserPoints(); 
424   
425              return; 
426          } 
427          super.actionPerformed(e); 
428      } 
429   
430      private void processUserPoints() { 
431          System.out.println("shapes.size()=" + userPoints.getSize()); 
432          Timer martelliTimer = new Timer(); 
433          martelliTimer.start(); 
434          processUserPoints(userPoints); 
435          martelliTimer.print("Martelli done"); 
436      } 
437  } 
438   
439   
440