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 "; 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 "; 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 }