/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