1 import java.awt.BasicStroke;
2 import java.awt.Color;
3 import java.awt.Graphics;
4 import java.awt.Graphics2D;
5 import java.awt.Image;
6 import java.awt.datatransfer.DataFlavor;
7 import java.awt.dnd.DnDConstants;
8 import java.awt.dnd.DropTarget;
9 import java.awt.dnd.DropTargetDragEvent;
10 import java.awt.dnd.DropTargetDropEvent;
11 import java.awt.dnd.DropTargetEvent;
12 import java.awt.dnd.DropTargetListener;
13 import java.awt.event.KeyEvent;
14 import java.awt.event.KeyListener;
15 import java.awt.event.MouseAdapter;
16 import java.awt.event.MouseEvent;
17 import java.awt.event.MouseMotionAdapter;
18 import java.io.BufferedWriter;
19 import java.io.File;
20 import java.io.FileWriter;
21 import java.util.Arrays;
22 import java.util.Iterator;
23 import java.util.LinkedList;
24 import java.util.List;
25
26 import javax.imageio.ImageIO;
27 import javax.swing.JFrame;
28 import javax.swing.JOptionPane;
29
30
31
32 public class DatasetAnnotated_BB_Occ extends JFrame implements DropTargetListener {
33
34 private static final long serialVersionUID = 1L;
35
36 private static String[] annoName = {
37 "Head",
38 "RUA", "RLA",
39 "Torse",
40 "LUA", "LLA",
41 "RUL", "RLL",
42 "LUL", "LLL"
43 };
44 //private static int[] annoNameIndex = {3, 0, 1, 2, 4, 5, 6, 7, 8, 9};
45 private static int[] annoNameIndex = {3, 0, 4, 5, 1, 2, 8, 9, 6, 7};
46
47 private static String[] annoName2 = {
48 "Head",
49 "LUA", "LLA",
50 "Torse",
51 "RUA", "RLA",
52 "LUL", "LLL",
53 "RUL", "RLL"
54 };
55 private static int[] annoNameIndex2 = {3, 0, 1, 2, 4, 5, 6, 7, 8, 9};
56
57 private static String[] symbolNameForAG = {
58 "Head",
59 "UA", "LA",
60 "Torse",
61 "UA", "LA",
62 "UL", "LL",
63 "UL", "LL"
64 };
65 private static String[] symbolNameForAOG = {
66 "Head",
67 "RUA", "LA",
68 "Torse",
69 "LUA", "LA",
70 "RUL", "RLL",
71 "LUL", "LLL"
72 };
73 private static String[] symbolName = {
74 "Head",
75 "RUA", "LA",
76 "Torse",
77 "LUA", "LA",
78 "RUL", "RLL",
79 "LUL", "LLL", // ************************
80 "UA", "LA", "UL", "LL"
81 };
82 private static String[] prodNameForAG = {
83 "Default", // Head, RUA, RLA, LUA, LLA, RUL, RLL, LUL, LLL
84 "Occluded", // RLA, LUA
85 "", // nothing
86 "", "", "", // nothing
87 "Wide", "Narrow" // Torse
88 };
89 private static String[] prodNameForAOG = {
90 "Default", // Head, RUA, RLA, LUA, LLA, RUL, RLL, LUL, LLL
91 "Occluded", // RLA, LUA
92 "", // nothing
93 "Right", "Left", "Front", // Head
94 "Wide", "Narrow" // Torse
95 };
96 private static String[] prodName = {
97 "Default",
98 "Front", "Left", "Right",
99 "Occluded",
100 "Wide", "Narrow"
101 };
102
103 private Image offScreenImage = null; // avoid flicker
104 private Graphics gOffScreenGraphics;
105
106 // handler of the annotated image
107 private Image initImage = null;
108 // path to the annotated dataset
109 private String path = null;
110 // the image name without extension
111 private String fileName = null;
112 // image file list
113 private LinkedList<File> file_list = new LinkedList<File>();
114 // index of images
115 private int curFileIdx = 0;
116
117 // if shift is pressed, then draw
118 // horizontal or
119 // vertical line.
120 private boolean shift_flag = false;
121
122 // flag to occlusion state
123 // 0: non-occluded, 1: partial-occluded, 2: full-occluded
124 private int[] isOccluded = new int[annoName.length];
125
126 // flag to production state
127 // 0: default,
128 // 1: occluded,
129 // 3: right, 4: left, 5: front,
130 // 6: wide, 7: narrow
131 private int[] isDefault = new int[annoName.length];
132 // ???
133 private int[] points = new int[annoName.length * 4];
134
135 // each part is annotated by two line
136 private static final int numXY = 4;
137 private int[][] xPoints = new int[annoName.length][numXY];
138 private int[][] yPoints = new int[annoName.length][numXY];
139
140 // index of parts
141 private int idx1 = 0;
142 // index of line points
143 private int idx2 = 0;
144
145 private static final double scale = 1;
146 private static final int _width = 300;
147 private static final int _height = 300;
148 private static final int _startX = 450;
149 private static final int _startY = 180;
150 private static final int border = 10;
151 private static final int _startJframeX = 0;
152 private static final int _startJframeY = 20;
153 private static final int _circleLen = 3;
154
155 public DatasetAnnotated_BB_Occ() {
156 //
157 setTitle("Dataset Annotation");
158 setSize(_width, _height);
159 setLocation(_startX, _startY);
160 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
161
162 // button1: êó±ê×ó?ü
163 // button2: êó±ê????
164 // button3: êó±êóò?ü
165 addMouseListener(new MouseAdapter() {
166 @Override
167 public void mouseClicked(MouseEvent e) {
168 System.out.println("mouse click " + e.getButton());
169
170 if (initImage == null || idx1 == annoName.length || e.getButton() == MouseEvent.BUTTON2)
171 return;
172
173 if (e.getButton() == MouseEvent.BUTTON3) {
174 xPoints[idx1][idx2] = 0;
175 yPoints[idx1][idx2] = 0;
176
177 idx2--;
178 if (idx2 < 0) {
179 // need to be reset
180 isDefault[idx1] = 0; // set to be default
181 isOccluded[idx1] = 2; // set to be full-occlusion
182
183 Arrays.fill(xPoints[idx1], 0);
184 Arrays.fill(yPoints[idx1], 0);
185
186 idx2 = 0;
187 }
188
189 DatasetAnnotated_BB_Occ.this.repaint();
190 return;
191 }
192
193 // get the point location
194 xPoints[idx1][idx2] = e.getX() - _startJframeX;
195 yPoints[idx1][idx2] = e.getY() - _startJframeY;
196
197 // System.out.println("mouse click point: (" + e.getX() + ", " + e.getY() + ")");
198 System.out.println("mouse click point: (" + xPoints[idx1][idx2] + ", " + yPoints[idx1][idx2] + ")");
199
200 if (xPoints[idx1][idx2] < border)
201 xPoints[idx1][idx2] = border;
202 if (xPoints[idx1][idx2] >= initImage.getWidth(null) + border)
203 xPoints[idx1][idx2] = initImage.getWidth(null) + border - 1;
204
205 if (yPoints[idx1][idx2] < border)
206 yPoints[idx1][idx2] = border;
207 if (yPoints[idx1][idx2] >= initImage.getHeight(null) + border)
208 yPoints[idx1][idx2] = initImage.getHeight(null) + border - 1;
209
210 if ((idx2 == 1 || idx2 == 3) && shift_flag && idx1 < annoName.length) {
211
212 if (xPoints[idx1][idx2] != xPoints[idx1][idx2 - 1] && yPoints[idx1][idx2] != yPoints[idx1][idx2 - 1]) {
213 double dy = yPoints[idx1][idx2] - yPoints[idx1][idx2 - 1] + 0.00;
214 double dx = xPoints[idx1][idx2] - xPoints[idx1][idx2 - 1] + 0.00;
215 double k = dy / dx;
216
217 if (Math.abs(k) <= 1) {
218 yPoints[idx1][idx2] = yPoints[idx1][idx2 - 1];
219 } else {
220 xPoints[idx1][idx2] = xPoints[idx1][idx2 - 1];
221 }
222 }
223 }
224
225 idx2++;
226 if (idx2 == numXY) {
227 //
228 isOccluded[idx1] = 0; // set to be visual
229 // isDefault[idx1] = ???
230
231 idx1++;
232 idx2 = 0;
233 } else if (idx2 == 1 || idx2 == 3) {
234 xPoints[idx1][idx2] = xPoints[idx1][idx2 - 1];
235 yPoints[idx1][idx2] = yPoints[idx1][idx2 - 1];
236 }
237
238 // repaint
239 DatasetAnnotated_BB_Occ.this.repaint();
240
241 //
242 if (idx1 == annoName.length) {
243 int choice = JOptionPane.showConfirmDialog(
244 DatasetAnnotated_BB_Occ.this,
245 "complete! save annotation or not?",
246 "tips",
247 JOptionPane.YES_NO_OPTION
248 );
249
250 if (choice == JOptionPane.YES_OPTION) {
251 // save the annotation
252 saveAnnotation();
253
254 // set next image
255 if (file_list.size() > 1)
256 setNextPic(1);
257 }
258 }
259 }
260
261 });
262
263 addMouseMotionListener(new MouseMotionAdapter() {
264
265 @Override
266 public void mouseMoved(MouseEvent e) {
267 if (initImage == null || idx1 == annoName.length || idx2 == 0)
268 return;
269
270 // System.out.println("mouse move");
271
272 // get the point location -- keep idx2
273 xPoints[idx1][idx2] = e.getX() - _startJframeX;
274 yPoints[idx1][idx2] = e.getY() - _startJframeY;
275 // System.out.println("mouse move point: (" + e.getX() + ", " + e.getY() + ")");
276 System.out.println("mouse click point: (" + xPoints[idx1][idx2] + ", " + yPoints[idx1][idx2] + ")");
277
278 if (xPoints[idx1][idx2] < border)
279 xPoints[idx1][idx2] = border;
280 if (xPoints[idx1][idx2] >= initImage.getWidth(null) + border)
281 xPoints[idx1][idx2] = initImage.getWidth(null) + border - 1;
282
283 if (yPoints[idx1][idx2] < border)
284 yPoints[idx1][idx2] = border;
285 if (yPoints[idx1][idx2] >= initImage.getHeight(null) + border)
286 yPoints[idx1][idx2] = initImage.getHeight(null) + border - 1;
287
288 if ( (idx2 == 1 || idx2 == 3) && shift_flag && idx1 < annoName.length ) {
289 if (xPoints[idx1][idx2] != xPoints[idx1][idx2 - 1] && yPoints[idx1][idx2] != yPoints[idx1][idx2 - 1]) {
290 double dy = yPoints[idx1][idx2] - yPoints[idx1][idx2 - 1] + 0.00;
291 double dx = xPoints[idx1][idx2] - xPoints[idx1][idx2 - 1] + 0.00;
292 double k = dy / dx;
293
294 if (Math.abs(k) <= 1) {
295 yPoints[idx1][idx2] = yPoints[idx1][idx2 - 1];
296 } else {
297 xPoints[idx1][idx2] = xPoints[idx1][idx2 - 1];
298 }
299 }
300 }
301
302 // repaint
303 repaint();
304 }
305 });
306
307 // 0: non-occluded, 1: partial-occluded, 2: full-occluded
308 // 3: right, 4: left, 5: front,
309 // 6: wide, 7: narrow
310 // u: back to pre-part
311 // n: ahead to next-part
312 // r: reset the current image
313 // s: save
314 // a: back to pre-image
315 // d: ahead to next image
316 addKeyListener(new KeyListener() {
317
318 @Override
319 public void keyTyped(KeyEvent e) {
320 }
321
322 // dose not modify
323 @Override
324 public void keyReleased(KeyEvent e) {
325 switch (e.getKeyCode()) {
326 case KeyEvent.VK_SHIFT:
327 shift_flag = false;
328 break;
329 }
330 }
331
332 // need to be modified
333 @Override
334 public void keyPressed(KeyEvent e) {
335
336 switch (Character.toLowerCase(e.getKeyChar())) {
337 // back to pre-part
338 case ‘u‘:
339 if (idx1 != 0) {
340 System.out.println("u" + " " + annoName[idx1]);
341
342 // current part -- need to be reset
343 Arrays.fill(xPoints[idx1], 0);
344 Arrays.fill(yPoints[idx1], 0);
345
346 isDefault[idx1] = 0; // set to be default
347 isOccluded[idx1] = 2; // set to be full-occlusion
348
349 //
350 if (idx2 == 0)
351 idx1--;
352 idx2 = 0;
353
354 // pre part - need to be reseted
355 isDefault[idx1] = 0; // set to be default
356 isOccluded[idx1] = 2; // set to be full-occlusion
357
358 Arrays.fill(xPoints[idx1], 0);
359 Arrays.fill(yPoints[idx1], 0);
360 }
361 break;
362
363 // save the annotation
364 case ‘s‘:
365 System.out.println("s" + " " + annoName[idx1] + " " + file_list.get(curFileIdx));
366 saveAnnotation();
367 break;
368
369 // ahead to next part
370 case ‘n‘:
371 // skip current annotation due to missing
372 if (idx1 >= annoName.length)
373 return;
374 System.out.println("n" + " " + annoName[idx1]);
375
376 Arrays.fill(xPoints[idx1], 0);
377 Arrays.fill(yPoints[idx1], 0);
378
379 isDefault[idx1] = 0; // set to be default
380 isOccluded[idx1] = 2; // set to be full-occlusion
381
382 idx1++;
383 if (idx1 == annoName.length) {
384 int choice = JOptionPane.showConfirmDialog(
385 DatasetAnnotated_BB_Occ.this,
386 "complete! save annotation or not?", "tips",
387 JOptionPane.YES_NO_OPTION
388 );
389
390 if (choice == JOptionPane.YES_OPTION) {
391 //
392 saveAnnotation();
393
394 // set and init next image
395 if (file_list.size() > 1)
396 setNextPic(1);
397 }
398 }
399
400 idx2 = 0;
401 break;
402
403 // back to pre image
404 case ‘a‘:
405 // set and init pre image
406 System.out.println("a" + " " + file_list.get(curFileIdx));
407 setNextPic(0);
408 break;
409
410 // ahead to next image
411 case ‘d‘:
412 // set and init next image
413
414 //saveAnnotation(); ?????
415 System.out.println("d" + " " + file_list.get(curFileIdx));
416 setNextPic(1);
417 break;
418
419 // reset the current image
420 case ‘r‘:
421 System.out.println("r" + " " + file_list.get(curFileIdx));
422
423 idx1 = 0;
424 idx2 = 0 ;
425
426 for(int i = 0; i < annoName.length; i++) {
427 Arrays.fill(xPoints[i], 0);
428 Arrays.fill(yPoints[i], 0);
429 }
430
431 Arrays.fill(isOccluded, 2);
432 Arrays.fill(isDefault, 0);
433 break;
434
435 // 1: partial occluded
436 case ‘1‘:
437 System.out.println("1" + " " + annoName[idx1]);
438 isOccluded[idx1] = 1;
439 break;
440
441 // 2: full occluded
442 case ‘2‘:
443 System.out.println("2" + " " + annoName[idx1]);
444 isOccluded[idx1] = 2;
445 break;
446
447 // 3: right
448 case ‘3‘:
449 System.out.println("3" + " " + annoName[idx1]);
450 isDefault[idx1] = 3;
451 break;
452
453 // 4: left
454 case ‘4‘:
455 System.out.println("4" + " " + annoName[idx1]);
456 isDefault[idx1] = 4;
457 break;
458
459 // 5: front
460 case ‘5‘:
461 System.out.println("5" + " " + annoName[idx1]);
462 isDefault[idx1] = 5;
463 break;
464
465 // 6: wide
466 case ‘6‘:
467 System.out.println("6" + " " + annoName[idx1]);
468 isDefault[idx1] = 6;
469 break;
470
471 // 7: narrow
472 case ‘7‘:
473 System.out.println("7" + " " + annoName[idx1]);
474 isDefault[idx1] = 7;
475 break;
476
477 default:
478 switch (e.getKeyCode()) {
479 case KeyEvent.VK_ESCAPE:
480 Arrays.fill(xPoints[idx1], 0);
481 Arrays.fill(yPoints[idx1], 0);
482 idx2 = 0;
483 break;
484
485 case KeyEvent.VK_SHIFT:
486 shift_flag = true;
487 break;
488 }
489 }
490
491 // repaint
492 DatasetAnnotated_BB_Occ.this.repaint();
493 }
494 });
495
496 new DropTarget(this, this);
497
498 setVisible(true);
499 }
500
501
502 protected void saveAnnotation() {
503 saveAnnotationForAG();
504 saveAnnotationForAOG();
505 }
506
507 protected void saveAnnotationForAG() {
508 try {
509 File file = new File(path + "/../AnnotationsForAG");
510 file.mkdir();
511 file = new File(path + "/../AnnotationsForAG/" + fileName + ".label");
512 BufferedWriter bw = new BufferedWriter(new FileWriter(file));
513
514 String str = "";
515 for (int j = 0; j < annoName.length; j++) {
516 int i = annoNameIndex[j];
517 //int i = annoNameIndex2[j];
518
519 //str = str + annoName[i];
520 str = str + annoName2[i];
521 str = str + " " + symbolNameForAOG[i] + " ";
522 str = str + prodNameForAOG[isDefault[i]] + " ";
523
524 // x - border
525 // y - border
526
527 // line 1
528 double x1 = Math.max( (xPoints[i][0] - border) / scale, 0 );
529 double y1 = Math.max( (yPoints[i][0] - border) / scale, 0 );
530
531 double x2 = Math.max( (xPoints[i][1] - border) / scale, 0 );
532 double y2 = Math.max( (yPoints[i][1] - border) / scale, 0 );
533
534 // line 2
535 double x3 = Math.max( (xPoints[i][2] - border) / scale, 0 );
536 double y3 = Math.max( (yPoints[i][2] - border) / scale, 0 );
537
538 double x4 = Math.max( (xPoints[i][3] - border) / scale, 0 );
539 double y4 = Math.max( (yPoints[i][3] - border) / scale, 0 );
540
541 double xx1, yy1; // bottom end point
542 double xx2, yy2; // top end point
543 double dx, dy;
544 // ?¤-------------------> x
545 // |
546 // |
547 // y
548
549 if(annoName[i].equals("Head")) {
550 xx1 = x2; yy1=y2;
551 xx2 = x1; yy2 = y1;
552
553 //dx = xx1 - xx2 + 0.00;
554 //dy = yy1 - yy2 + 0.00;
555 } else {
556 xx1 = x1; yy1 = y1;
557 xx2 = x2; yy2 = y2;
558
559 //dx = xx2 - xx1 + 0.00;
560 //dy = yy2 - yy1 + 0.00;
561 }
562
563 //
564 dx = xx2 - xx1 + 0.00;
565 dy = yy2 - yy1 + 0.00;
566
567 /*
568 * public static double atan2(double y, double x)
569 * Returns the angle theta from the conversion of rectangular coordinates (x, y)
570 * to polar coordinates (r, theta). This method computes the phase theta
571 * by computing an arc tangent of y/x in the range of -pi to pi.
572 */
573 double orientation = Math.atan2(dy, dx);
574 // double orientation = 0;
575 // if(x1 == x2)
576 // orientation = Math.PI / 2;
577 // else {
578 // orientation = Math.atan(dy / dx);
579 //
580 // }
581
582 double length = Math.sqrt( (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) );
583 double prodWidth = Math.sqrt( (x3 - x4) * (x3 - x4) + (y3 - y4) * (y3 - y4) );
584 double distWidth = prodWidth;
585
586 str = str + xx1 + " " + yy1 + " " + orientation;
587 str = str + " " + length + " " + prodWidth + " " + distWidth;
588 str = str + " " + isOccluded[i] + " 0 \n";
589 }
590
591 bw.write(str);
592 bw.close();
593
594 } catch (Exception e) {
595 e.printStackTrace();
596 JOptionPane.showMessageDialog(this, "failed to save annotation");
597 }
598 }
599
600 protected void saveAnnotationForAOG() {
601 try {
602 File file = new File(path + "/../AnnotationsForAOG");
603 file.mkdir();
604 file = new File(path + "/../AnnotationsForAOG/" + fileName + ".label");
605 BufferedWriter bw = new BufferedWriter(new FileWriter(file));
606
607 String str = "";
608 for (int j = 0; j < annoName.length; j++) {
609 int i = annoNameIndex[j];
610 //int i = annoNameIndex2[j];
611
612 //str = str + annoName[i];
613 str = str + annoName2[i];
614 str = str + " " + symbolNameForAOG[i] + " ";
615 str = str + prodNameForAOG[isDefault[i]] + " ";
616
617 // x - border
618 // y - border
619
620 // line 1
621 double x1 = Math.max( (xPoints[i][0] - border) / scale, 0 );
622 double y1 = Math.max( (yPoints[i][0] - border) / scale, 0 );
623
624 double x2 = Math.max( (xPoints[i][1] - border) / scale, 0 );
625 double y2 = Math.max( (yPoints[i][1] - border) / scale, 0 );
626
627 // line 2
628 double x3 = Math.max( (xPoints[i][2] - border) / scale, 0 );
629 double y3 = Math.max( (yPoints[i][2] - border) / scale, 0 );
630
631 double x4 = Math.max( (xPoints[i][3] - border) / scale, 0 );
632 double y4 = Math.max( (yPoints[i][3] - border) / scale, 0 );
633
634 double xx1, yy1; // bottom end point
635 double xx2, yy2; // top end point
636 double dx, dy;
637 // ?¤-------------------> x
638 // |
639 // |
640 // y
641
642 if(annoName[i].equals("Head")) {
643 xx1 = x2; yy1=y2;
644 xx2 = x1; yy2 = y1;
645
646 //dx = xx1 - xx2 + 0.00;
647 //dy = yy1 - yy2 + 0.00;
648 } else {
649 xx1 = x1; yy1 = y1;
650 xx2 = x2; yy2 = y2;
651
652 //dx = xx2 - xx1 + 0.00;
653 //dy = yy2 - yy1 + 0.00;
654 }
655
656 //
657 dx = xx2 - xx1 + 0.00;
658 dy = yy2 - yy1 + 0.00;
659
660 /*
661 * public static double atan2(double y, double x)
662 * Returns the angle theta from the conversion of rectangular coordinates (x, y)
663 * to polar coordinates (r, theta). This method computes the phase theta
664 * by computing an arc tangent of y/x in the range of -pi to pi.
665 */
666 double orientation = Math.atan2(dy, dx);
667 // double orientation = 0;
668 // if(x1 == x2)
669 // orientation = Math.PI / 2;
670 // else {
671 // orientation = Math.atan(dy / dx);
672 //
673 // }
674
675 double length = Math.sqrt( (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) );
676 double prodWidth = Math.sqrt( (x3 - x4) * (x3 - x4) + (y3 - y4) * (y3 - y4) );
677 double distWidth = prodWidth;
678
679 str = str + xx1 + " " + yy1 + " " + orientation;
680 str = str + " " + length + " " + prodWidth + " " + distWidth;
681 str = str + " " + isOccluded[i] + " 0 \n";
682 }
683
684 bw.write(str);
685 bw.close();
686
687 } catch (Exception e) {
688 e.printStackTrace();
689 JOptionPane.showMessageDialog(this, "failed to save annotation");
690 }
691 }
692
693 @Override
694 public void update(Graphics g) {
695 if (initImage == null)
696 return;
697
698 if (offScreenImage == null
699 || offScreenImage.getHeight(this) != this.getHeight()
700 || offScreenImage.getWidth(this) != this.getWidth() ) {
701
702 offScreenImage = this.createImage(this.getWidth(), this.getHeight());
703
704 gOffScreenGraphics = offScreenImage.getGraphics();
705 }
706
707 int imgWidth = initImage.getWidth(null);
708 int imgHeigth = initImage.getHeight(null);
709
710 int oImgWidth = offScreenImage.getWidth(null);
711 int oImgHeight = offScreenImage.getHeight(null);
712
713 System.out.println("imgWidth: " + imgWidth + ", imgHeight: " + imgHeigth +
714 ", oImgWidth: " + oImgWidth + ", oImgHeight: " + oImgHeight);
715
716 // a top-left corner (border, border)
717 gOffScreenGraphics.drawImage(initImage, border, border, this);
718
719 ((Graphics2D) gOffScreenGraphics).setStroke(new BasicStroke(1.50f));
720 gOffScreenGraphics.setColor(Color.YELLOW);
721
722 if (idx1 < annoName.length)
723 gOffScreenGraphics.drawString(annoName[idx1], 10, 20);
724 else
725 gOffScreenGraphics.drawString("annotatation is done!", 10, 50);
726
727 // draw the current line
728 for (int i = 0; i < idx2; i += 2) {
729 gOffScreenGraphics.drawLine(xPoints[idx1][i], yPoints[idx1][i],
730 xPoints[idx1][i + 1], yPoints[idx1][i + 1]);
731 }
732
733 // draw the pre lines
734 gOffScreenGraphics.setColor(Color.GREEN);
735 for (int i = 0; i < idx1 && i < annoName.length; i++)
736 for(int j = 0; j < numXY; j += 2) {
737 // gOffScreenGraphics.drawLine(xPoints[i][j], yPoints[i][j], xPoints[i][j + 1], yPoints[i][j + 1]);
738 // gOffScreenGraphics.drawOval(xPoints[i][j], yPoints[i][j], _circleLen, _circleLen);
739 // gOffScreenGraphics.drawOval(xPoints[i][j + 1], yPoints[i][j + 1], _circleLen, _circleLen);
740
741 // gOffScreenGraphics.fillOval(xPoints[i][j], yPoints[i][j], _circleLen, _circleLen);
742 // gOffScreenGraphics.fillOval(xPoints[i][j + 1], yPoints[i][j + 1], _circleLen, _circleLen);
743 if(j < 1) {
744 gOffScreenGraphics.drawLine(xPoints[i][j], yPoints[i][j], xPoints[i][j + 1], yPoints[i][j + 1]);
745 } else {
746 gOffScreenGraphics.fillOval(xPoints[i][j], yPoints[i][j], _circleLen, _circleLen);
747 gOffScreenGraphics.fillOval(xPoints[i][j + 1], yPoints[i][j + 1], _circleLen, _circleLen);
748 }
749 }
750
751 // paint(gOffScreen);
752 g.drawImage(offScreenImage, _startJframeX, _startJframeY, this);
753 g.dispose();
754 }
755
756 @Override
757 public void paint(Graphics g) {
758 update(g);
759 }
760
761 @Override
762 public void dragEnter(DropTargetDragEvent dtde) {
763 }
764
765 @Override
766 public void dragOver(DropTargetDragEvent dtde) {
767 }
768
769 @Override
770 public void dropActionChanged(DropTargetDragEvent dtde) {
771 }
772
773 @Override
774 public void dragExit(DropTargetEvent dte) {
775 }
776
777 // drop the images into UI
778 // get the image file list
779 @SuppressWarnings("rawtypes")
780 @Override
781 public void drop(DropTargetDropEvent dtde) {
782 try {
783 if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
784 dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
785
786 List list = (List) (dtde.getTransferable()
787 .getTransferData(DataFlavor.javaFileListFlavor));
788
789 Iterator iterator = list.iterator();
790 file_list.clear();
791 curFileIdx = -1;
792
793 while (iterator.hasNext()) {
794 File file = (File) iterator.next();
795 if (file.isDirectory()) {
796 addFileToQueue(file);
797 } else {
798 if (file.getName().endsWith(".jpg") || file.getName().endsWith(".png"))
799 file_list.add(file);
800 }
801 }
802
803 setNextPic(1);
804 dtde.dropComplete(true);
805 } else {
806 dtde.rejectDrop();
807 }
808 } catch (Exception e) {
809 e.printStackTrace();
810 dtde.rejectDrop();
811 JOptionPane.showMessageDialog(this, "Failed to open image");
812 }
813 }
814
815 // flag == 0 -- previous pic
816 // flag == 1 -- next pic
817 private void setNextPic(int flag) {
818 int tmp = curFileIdx;
819
820 if (flag == 0) {
821 if (curFileIdx == 0) {
822 JOptionPane.showMessageDialog(this, "The first one!");
823 return;
824 }
825 curFileIdx--;
826 } else {
827 curFileIdx++;
828 }
829
830 boolean ok = false;
831 while (!ok) {
832 try {
833 if (curFileIdx >= file_list.size()) {
834 curFileIdx = tmp;
835 if (curFileIdx == -1)
836 return;
837 JOptionPane.showMessageDialog(this, "The last one!");
838 return;
839 }
840 File file = file_list.get(curFileIdx);
841
842
843 initImage = ImageIO.read(file);
844
845 initImage = initImage.getScaledInstance(
846 (int) (initImage.getWidth(null) * scale),
847 (int) (initImage.getHeight(null) * scale),
848 Image.SCALE_SMOOTH); // SCALE_DEFAULT, SCALE_SMOOTH
849
850 // path and fileName
851 path = file.getParent();
852 fileName = file.getName();
853
854 int imgLen = file_list.size();
855 setTitle(imgLen + " images - " + fileName);
856
857 int idx = fileName.lastIndexOf(‘.‘);
858 if (idx != -1)
859 fileName = fileName.substring(0, idx);
860
861 idx1 = 0;
862 idx2 = 0;
863
864 // set default value
865 Arrays.fill(isOccluded, 2); // full occluded
866 Arrays.fill(isDefault, 0); // default
867 Arrays.fill(points, 0);
868
869 for (int i = 0; i < annoName.length; i++) {
870 Arrays.fill(xPoints[i], 0);
871 Arrays.fill(yPoints[i], 0);
872 }
873
874 setSize(initImage.getWidth(null) + border * 3 + _startJframeX,
875 initImage.getHeight(null) + border * 3 + _startJframeY
876 );
877
878 // readAnnotation(path + "/Annotations/" + fileName + ".xml");
879 repaint();
880
881 ok = true;
882
883 } catch (Exception e) {
884 e.printStackTrace();
885 if (flag == 0) {
886 if (curFileIdx == 0) {
887 return;
888 }
889 curFileIdx--;
890 } else {
891 curFileIdx++;
892 }
893 }
894 }
895 }
896
897 private void addFileToQueue(File folder) {
898 for (File file : folder.listFiles()) {
899 if (file.isDirectory())
900 addFileToQueue(file);
901 else
902 if (file.getName().endsWith(".jpg") || file.getName().endsWith(".png"))
903 file_list.add(file);
904 }
905 }
906
907 private boolean readAnnotation(String path) {
908 File gt = new File(path);
909 if (!gt.exists())
910 return false;
911
912 int choice = JOptionPane.showConfirmDialog(this,
913 "Annotation file is found, read it or not?", "tips",
914 JOptionPane.YES_NO_OPTION);
915 if (choice != JOptionPane.YES_OPTION)
916 return false;
917
918 try {
919 } catch (Exception e) {
920 e.printStackTrace();
921 idx1 = 0;
922 idx2 = 0;
923 for (int i = 0; i < 6; i++) {
924 Arrays.fill(xPoints[i], 0);
925 Arrays.fill(yPoints[i], 0);
926 }
927 JOptionPane.showMessageDialog(this, "Invalid annotation file");
928 }
929 return true;
930 }
931
932 public static void main(String[] args) {
933 new DatasetAnnotated_BB_Occ();
934 }
935
936 }