annotation code for human pose estimation

参考论文:
   http://www.cs.ucla.edu/~rothrock/pages/cvpr13/


在标注part的时候 先标注part的状态,然后才标注part的bounding box 

用一条直线和两个点(这两个点是另外一条直线的简化)来表示,即模拟一个bounding box,为了方便标注,其中 non-occluded 和 Default 是默认的)

*******************************

鼠标左键:确认点和当前线段
鼠标右键:取消点和当前线段

0: non-occluded,        // default
1: partial-occluded, 
2: full-occluded        
3: right,                     // head
4: left,                       // head
5: front,                    // head
6: wide,                     // torse
7: narrow                  // torse
u: back to pre-part
n: ahead to next-part
r: reset the current image
s: save
a: back to pre-image
d: ahead to next image


********************************

图片示例:

annotation code for human pose estimation_第1张图片


********************************


import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JOptionPane;



public class DatasetAnnotated_BB_Occ extends JFrame implements DropTargetListener {

	private static final long serialVersionUID = 1L;

	private static String[] annoName = { 
		"Head", 
		"LUA", "LLA",
		"Torse", 
		"RUA", "RLA",		 
		"LUL", "LLL",
		"RUL", "RLL"
	};
	//private static int[] annoNameIndex = {3, 0, 1, 2, 4, 5, 6, 7, 8, 9};
	private static int[] annoNameIndex = {3, 0, 4, 5, 1, 2, 8, 9, 6, 7};
	
	private static String[] symbolNameForAG = { 
		"Head", 
		"UA", "LA", 
		"Torse", 
		"UA", "LA", 
		"UL", "LL", 
		"UL", "LL"
	};
	private static String[] symbolNameForAOG = { 
		"Head",
		"LUA", "LA",
		"Torse", 
		"RUA", "LA",		 
		"LUL", "LLL",
		"RUL", "RLL"
	};
	private static String[] symbolName = { 
		"Head",
		"RUA", "LA",
		"Torse", 
		"LUA", "LA",
		"RUL", "RLL", 
		"LUL", "LLL",				// ************************
		"UA", "LA", "UL", "LL"
	};
	private static String[] prodNameForAG = { 
		"Default", 						// Head, RUA, RLA, LUA, LLA, RUL, RLL, LUL, LLL
		"Occluded", 					// RLA, LUA
		"",								// nothing
		"", "", "", 					// nothing					
		"Wide", "Narrow"				// Torse
	};
	private static String[] prodNameForAOG = { 
		"Default", 						// Head, RUA, RLA, LUA, LLA, RUL, RLL, LUL, LLL
		"Occluded", 					// RLA, LUA
		"",								// nothing
		"Right", "Left", "Front", 		// Head					
		"Wide", "Narrow"				// Torse
	};
	private static String[] prodName = { 
		"Default", 
		"Occluded",
		"",
		"Right", "Left", "Front", 
		"Wide", "Narrow"
	};

	private Image offScreenImage = null; // avoid flicker
	private Graphics gOffScreenGraphics;

	// handler of the annotated image
	private Image initImage = null;
	// path to the annotated dataset
	private String path = null;
	// the image name without extension
	private String fileName = null;
	// image file list
	private LinkedList<File> file_list = new LinkedList<File>();
	// index of images
	private int curFileIdx = 0;

	// if shift is pressed, then draw
	// horizontal or
	// vertical line.
	private boolean shift_flag = false; 

	// flag to occlusion state
	// 0: non-occluded, 1: partial-occluded, 2: full-occluded
	private int[] isOccluded = new int[annoName.length];
	
	// flag to production state
	// 0: default,
	// 1: occluded, 
	// 3: right, 4: left, 5: front,
	// 6: wide, 7: narrow 
	private int[] isDefault = new int[annoName.length];
	// ???
	private int[] points = new int[annoName.length * 4];

	// each part is annotated by two line
	private static final int numXY = 4;
	private int[][] xPoints = new int[annoName.length][numXY];
	private int[][] yPoints = new int[annoName.length][numXY];
	
	// index of parts
	private int idx1 = 0;
	// index of line points
	private int idx2 = 0;
	
	private static final double scale = 1;
	private static final int _width = 300;
	private static final int _height = 300;
	private static final int _startX = 450;
	private static final int _startY = 180;
	private static final int border = 10;
	private static final int _startJframeX = 0;
	private static final int _startJframeY = 20;
	private static final int _circleLen = 3;
	
	public DatasetAnnotated_BB_Occ() {
		// 
		setTitle("Dataset Annotation");
		setSize(_width, _height);
		setLocation(_startX, _startY);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		// button1: the left mouse button
		// button2: the mouse wheel
		// button3: the right mouse button
		addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				System.out.println("mouse click " + e.getButton());
				
				if (initImage == null || idx1 == annoName.length || e.getButton() == MouseEvent.BUTTON2)
					return;

				if (e.getButton() == MouseEvent.BUTTON3) {
					xPoints[idx1][idx2] = 0;
					yPoints[idx1][idx2] = 0;
					
					idx2--;
					if (idx2 < 0) {
						// need to be reset
						isDefault[idx1]  = 0;	// set to be default
						isOccluded[idx1] = 2;	// set to be full-occlusion
						
						Arrays.fill(xPoints[idx1], 0);
						Arrays.fill(yPoints[idx1], 0);
						
						idx2 = 0;
					}
					
					DatasetAnnotated_BB_Occ.this.repaint();
					return;
				}
				
				// get the point location
				xPoints[idx1][idx2] = e.getX() - _startJframeX;
				yPoints[idx1][idx2] = e.getY() - _startJframeY;
				
//				System.out.println("mouse click point: (" + e.getX() + ", " + e.getY() + ")");
				System.out.println("mouse click point: (" + xPoints[idx1][idx2] + ", " + yPoints[idx1][idx2] + ")");

				if (xPoints[idx1][idx2] < border)
					xPoints[idx1][idx2] = border;
				if (xPoints[idx1][idx2] >= initImage.getWidth(null) + border)
					xPoints[idx1][idx2] = initImage.getWidth(null) + border - 1;

				if (yPoints[idx1][idx2] < border)
					yPoints[idx1][idx2] = border;
				if (yPoints[idx1][idx2] >= initImage.getHeight(null) + border)
					yPoints[idx1][idx2] = initImage.getHeight(null) + border - 1;

				if ((idx2 == 1 || idx2 == 3) && shift_flag && idx1 < annoName.length) {
					
					if (xPoints[idx1][idx2] != xPoints[idx1][idx2 - 1] && yPoints[idx1][idx2] != yPoints[idx1][idx2 - 1]) {
						double dy = yPoints[idx1][idx2] - yPoints[idx1][idx2 - 1] + 0.00;
						double dx = xPoints[idx1][idx2] - xPoints[idx1][idx2 - 1] + 0.00;
						double k =  dy / dx;
						
						if (Math.abs(k) <= 1) {
							yPoints[idx1][idx2] = yPoints[idx1][idx2 - 1];
						} else {
							xPoints[idx1][idx2] = xPoints[idx1][idx2 - 1];
						}
					}
				}

				idx2++;
				if (idx2 == numXY) {
					// 
					isOccluded[idx1] = 0;		// set to be visual
					// isDefault[idx1] = ???
					
					idx1++;
					idx2 = 0;
				} else if (idx2 == 1 || idx2 == 3) {
					xPoints[idx1][idx2] = xPoints[idx1][idx2 - 1];
					yPoints[idx1][idx2] = yPoints[idx1][idx2 - 1];
				}

				// repaint
				DatasetAnnotated_BB_Occ.this.repaint();

				// 
				if (idx1 == annoName.length) {
					int choice = JOptionPane.showConfirmDialog(
							DatasetAnnotated_BB_Occ.this,
							"complete! save annotation or not?", 
							"tips",
							JOptionPane.YES_NO_OPTION
							);
					
				if (choice == JOptionPane.YES_OPTION) {
					// save the annotation
					saveAnnotation();
					
					// set next image
					if (file_list.size() > 1)
						setNextPic(1);
					}
				}
			}

		});

		addMouseMotionListener(new MouseMotionAdapter() {

			@Override
			public void mouseMoved(MouseEvent e) {
				if (initImage == null || idx1 == annoName.length || idx2 == 0)
					return;
				
				// System.out.println("mouse move");
				
				// get the point location -- keep idx2 
				xPoints[idx1][idx2] = e.getX() - _startJframeX;
				yPoints[idx1][idx2] = e.getY() - _startJframeY;
				// System.out.println("mouse move point: (" + e.getX() + ", " + e.getY() + ")");
				System.out.println("mouse click point: (" + xPoints[idx1][idx2] + ", " + yPoints[idx1][idx2] + ")");
				
				if (xPoints[idx1][idx2] < border)
					xPoints[idx1][idx2] = border;
				if (xPoints[idx1][idx2] >= initImage.getWidth(null) + border)
					xPoints[idx1][idx2] = initImage.getWidth(null) + border - 1;

				if (yPoints[idx1][idx2] < border)
					yPoints[idx1][idx2] = border;
				if (yPoints[idx1][idx2] >= initImage.getHeight(null) + border)
					yPoints[idx1][idx2] = initImage.getHeight(null) + border - 1;

				if ( (idx2 == 1 || idx2 == 3) && shift_flag && idx1 < annoName.length ) {
					if (xPoints[idx1][idx2] != xPoints[idx1][idx2 - 1] && yPoints[idx1][idx2] != yPoints[idx1][idx2 - 1]) {
						double dy = yPoints[idx1][idx2] - yPoints[idx1][idx2 - 1] + 0.00;
						double dx = xPoints[idx1][idx2] - xPoints[idx1][idx2 - 1] + 0.00;
						double k =  dy / dx;
						
						if (Math.abs(k) <= 1) {
							yPoints[idx1][idx2] = yPoints[idx1][idx2 - 1];
						} else {
							xPoints[idx1][idx2] = xPoints[idx1][idx2 - 1];
						}
					}
				}
				
				// repaint
				repaint();
			}
		});

		// 0: non-occluded, 1: partial-occluded, 2: full-occluded
		// 3: right, 4: left, 5: front,
		// 6: wide, 7: narrow 
		// u: back to pre-part
		// n: ahead to next-part
		// r: reset the current image
		// s: save
		// a: back to pre-image
		// d: ahead to next image
		addKeyListener(new KeyListener() {

			@Override
			public void keyTyped(KeyEvent e) {
			}

			// dose not modify
			@Override
			public void keyReleased(KeyEvent e) {
				switch (e.getKeyCode()) {
				case KeyEvent.VK_SHIFT:
					shift_flag = false;
					break;
				}
			}

			// need to be modified
			@Override
			public void keyPressed(KeyEvent e) {

				switch (Character.toLowerCase(e.getKeyChar())) {
				//  back to pre-part
				case 'u':
					if (idx1 != 0) {
						System.out.println("u" + " " + annoName[idx1]);
						
						// current part -- need to be reset
						Arrays.fill(xPoints[idx1], 0);
						Arrays.fill(yPoints[idx1], 0);
						
						isDefault[idx1]  = 0;	// set to be default
						isOccluded[idx1] = 2;	// set to be full-occlusion
						
						//
						if (idx2 == 0)
							idx1--;
						idx2 = 0;
						
						// pre part - need to be reseted
						isDefault[idx1]  = 0;	// set to be default
						isOccluded[idx1] = 2;	// set to be full-occlusion
						
						Arrays.fill(xPoints[idx1], 0);
						Arrays.fill(yPoints[idx1], 0);
					}
					break;
					
				// save the annotation
				case 's':
					System.out.println("s" + " " + annoName[idx1] + " " + file_list.get(curFileIdx));
					saveAnnotation();
					break;
					
				// ahead to next part
				case 'n':
					// skip current annotation due to missing
					if (idx1 >= annoName.length)
						return;
					System.out.println("n" + " " + annoName[idx1]);
					
					Arrays.fill(xPoints[idx1], 0);
					Arrays.fill(yPoints[idx1], 0);
					
					isDefault[idx1]  = 0;	// set to be default
					isOccluded[idx1] = 2;	// set to be full-occlusion
					
					idx1++;
					if (idx1 == annoName.length) {
						int choice = JOptionPane.showConfirmDialog(
								DatasetAnnotated_BB_Occ.this,
								"complete! save annotation or not?", "tips",
								JOptionPane.YES_NO_OPTION
								);
						
						if (choice == JOptionPane.YES_OPTION) {
							// 
							saveAnnotation();
							
							// set and init next image
							if (file_list.size() > 1)
								setNextPic(1);
						}
					}
					
					idx2 = 0;
					break;

				// back to pre image
				case 'a':
					// set and init pre image
					System.out.println("a" + " " + file_list.get(curFileIdx));
					setNextPic(0);
					break;
				
				// ahead to next image
				case 'd':
					// set and init next image
					
					//saveAnnotation();   ?????
					System.out.println("d" + " " + file_list.get(curFileIdx));
					setNextPic(1);
					break;

				// reset the current image
				case 'r':
					System.out.println("r" + " " + file_list.get(curFileIdx));
					
					idx1 = 0;
					idx2 = 0 ;
					
					for(int i = 0; i < annoName.length; i++) {
						Arrays.fill(xPoints[i], 0);
						Arrays.fill(yPoints[i], 0);
					}
					
					Arrays.fill(isOccluded, 2);
					Arrays.fill(isDefault,  0);
					break;
				
				// 1: partial occluded
				case '1':
					System.out.println("1" + " " + annoName[idx1]);
					isOccluded[idx1] = 1;
					break;
					
				// 2: full occluded
				case '2':
					System.out.println("2" + " " + annoName[idx1]);
					isOccluded[idx1] = 2;
					break;
					
				// 3: right
				case '3':
					System.out.println("3" + " " + annoName[idx1]);
					isDefault[idx1] = 3;
					break;
					
				// 4: left
				case '4':
					System.out.println("4" + " " + annoName[idx1]);
					isDefault[idx1] = 4;
					break;
					
				// 5: front
				case '5':
					System.out.println("5" + " " + annoName[idx1]);
					isDefault[idx1] = 5;
					break;
					
				// 6: wide
				case '6':
					System.out.println("6" + " " + annoName[idx1]);
					isDefault[idx1] = 6;
					break;
					
				// 7: narrow
				case '7':
					System.out.println("7" + " " + annoName[idx1]);
					isDefault[idx1] = 7;
					break;
					
				default:
					switch (e.getKeyCode()) {
					case KeyEvent.VK_ESCAPE:
						Arrays.fill(xPoints[idx1], 0);
						Arrays.fill(yPoints[idx1], 0);
						idx2 = 0;
						break;

					case KeyEvent.VK_SHIFT:
						shift_flag = true;
						break;
					}
				}
				
				// repaint
				DatasetAnnotated_BB_Occ.this.repaint();
			}
		});

		new DropTarget(this, this);

		setVisible(true);
	}
	
	protected void saveAnnotation() {
		saveAnnotationForAG();
		saveAnnotationForAOG();
	}
	
	protected void saveAnnotationForAG() {
		try {
			File file = new File(path + "/../AnnotationsForAG");
			file.mkdir();
			file = new File(path + "/../AnnotationsForAG/" + fileName + ".label");
			BufferedWriter bw = new BufferedWriter(new FileWriter(file));
			
			String str = "";
			for (int j = 0; j < annoName.length; j++) {
				int i = annoNameIndex[j];				
				str = str + annoName[i];
				
				str = str + " " + symbolNameForAOG[i] + " ";
				str = str + prodNameForAOG[isDefault[i]] + " ";
						
				// x - border
				// y - border
				
				// line 1
				double x1 = Math.max( (xPoints[i][0] - border) / scale, 0 );	
				double y1 = Math.max( (yPoints[i][0] - border) / scale, 0 );
				
				double x2 = Math.max( (xPoints[i][1] - border) / scale, 0 );
				double y2 = Math.max( (yPoints[i][1] - border) / scale, 0 );
				
				// line 2
				double x3 = Math.max( (xPoints[i][2] - border) / scale, 0 );	
				double y3 = Math.max( (yPoints[i][2] - border) / scale, 0 );
				
				double x4 = Math.max( (xPoints[i][3] - border) / scale, 0 );
				double y4 = Math.max( (yPoints[i][3] - border) / scale, 0 );
				
				double xx1, yy1;	// bottom end point
				double xx2, yy2;	// top end point
				double dx, dy;
				// ·-------------------> x
				// |
				// |
				// y
				
				if(annoName[i].equals("Head")) {
					xx1 = x2; yy1=y2;
					xx2 = x1; yy2 = y1;
					
					//dx = xx1 - xx2 + 0.00;
					//dy = yy1 - yy2 + 0.00;
				} else {
					xx1 = x1; yy1 = y1;
					xx2 = x2; yy2 = y2;
					
					//dx = xx2 - xx1 + 0.00;
					//dy = yy2 - yy1 + 0.00;
				}
				
				//
				dx = xx2 - xx1 + 0.00;
				dy = yy2 - yy1 + 0.00;
				
				/*
				 * public static double atan2(double y, double x)
				 * Returns the angle theta from the conversion of rectangular coordinates (x, y) 
				 * to polar coordinates (r, theta). This method computes the phase theta 
				 * by computing an arc tangent of y/x in the range of -pi to pi.
				*/
				double orientation = Math.atan2(dy, dx);
//					double orientation = 0;
//					if(x1 == x2) 
//						orientation = Math.PI / 2;
//					else {
//						orientation = Math.atan(dy / dx);
//						
//					}
				
				double length    = Math.sqrt( (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) );
				double prodWidth = Math.sqrt( (x3 - x4) * (x3 - x4) + (y3 - y4) * (y3 - y4) );
				double distWidth = prodWidth;
				
				str = str + xx1 + " " + yy1 + " " + orientation;
				str = str + " " + length + " " + prodWidth + " " + distWidth; 
				str = str + " " + isOccluded[i] + " 0 \n";
			}
		
			bw.write(str);
			bw.close();

		} catch (Exception e) {
			e.printStackTrace();
			JOptionPane.showMessageDialog(this, "failed to save annotation");
		}
	}

	protected void saveAnnotationForAOG() {
		try {
			File file = new File(path + "/../AnnotationsForAOG");
			file.mkdir();
			file = new File(path + "/../AnnotationsForAOG/" + fileName + ".label");
			BufferedWriter bw = new BufferedWriter(new FileWriter(file));

			String str = "";
			for (int j = 0; j < annoName.length; j++) {
				int i = annoNameIndex[j];				
				str = str + annoName[i];
				str = str + " " + symbolNameForAOG[i] + " ";
				str = str + prodNameForAOG[isDefault[i]] + " ";
						
				// x - border
				// y - border
				
				// line 1
				double x1 = Math.max( (xPoints[i][0] - border) / scale, 0 );	
				double y1 = Math.max( (yPoints[i][0] - border) / scale, 0 );
				
				double x2 = Math.max( (xPoints[i][1] - border) / scale, 0 );
				double y2 = Math.max( (yPoints[i][1] - border) / scale, 0 );
				
				// line 2
				double x3 = Math.max( (xPoints[i][2] - border) / scale, 0 );	
				double y3 = Math.max( (yPoints[i][2] - border) / scale, 0 );
				
				double x4 = Math.max( (xPoints[i][3] - border) / scale, 0 );
				double y4 = Math.max( (yPoints[i][3] - border) / scale, 0 );
				
				double xx1, yy1;	// bottom end point
				double xx2, yy2;	// top end point
				double dx, dy;
				// ·-------------------> x
				// |
				// |
				// y
				
				if(annoName[i].equals("Head")) {
					xx1 = x2; yy1=y2;
					xx2 = x1; yy2 = y1;
					
					//dx = xx1 - xx2 + 0.00;
					//dy = yy1 - yy2 + 0.00;
				} else {
					xx1 = x1; yy1 = y1;
					xx2 = x2; yy2 = y2;
					
					//dx = xx2 - xx1 + 0.00;
					//dy = yy2 - yy1 + 0.00;
				}
				
				// 
				dx = xx2 - xx1 + 0.00;
				dy = yy2 - yy1 + 0.00;
				
				/*
				 * public static double atan2(double y, double x)
				 * Returns the angle theta from the conversion of rectangular coordinates (x, y) 
				 * to polar coordinates (r, theta). This method computes the phase theta 
				 * by computing an arc tangent of y/x in the range of -pi to pi.
				*/
				double orientation = Math.atan2(dy, dx);
//					double orientation = 0;
//					if(x1 == x2) 
//						orientation = Math.PI / 2;
//					else {
//						orientation = Math.atan(dy / dx);
//						
//					}
				
				double length    = Math.sqrt( (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) );
				double prodWidth = Math.sqrt( (x3 - x4) * (x3 - x4) + (y3 - y4) * (y3 - y4) );
				double distWidth = prodWidth;
				
				str = str + xx1 + " " + yy1 + " " + orientation;
				str = str + " " + length + " " + prodWidth + " " + distWidth; 
				str = str + " " + isOccluded[i] + " 0 \n";
			}
			
			bw.write(str);
			bw.close();

		} catch (Exception e) {
			e.printStackTrace();
			JOptionPane.showMessageDialog(this, "failed to save annotation");
		}
	}

	@Override
	public void update(Graphics g) {
		if (initImage == null)
			return;

		if (offScreenImage == null
				|| offScreenImage.getHeight(this) != this.getHeight()
				|| offScreenImage.getWidth(this) != this.getWidth() ) {
			
			offScreenImage = this.createImage(this.getWidth(), this.getHeight());
			
			gOffScreenGraphics = offScreenImage.getGraphics();
		}
		
		int imgWidth = initImage.getWidth(null);
		int imgHeigth = initImage.getHeight(null);
		
		int oImgWidth = offScreenImage.getWidth(null);
		int oImgHeight = offScreenImage.getHeight(null);
		
		System.out.println("imgWidth: " + imgWidth + ", imgHeight: " + imgHeigth + 
				", oImgWidth: " + oImgWidth + ", oImgHeight: " + oImgHeight);

		// a top-left corner (border, border)
		gOffScreenGraphics.drawImage(initImage, border, border, this); 
		
		((Graphics2D) gOffScreenGraphics).setStroke(new BasicStroke(1.50f));
		gOffScreenGraphics.setColor(Color.YELLOW);
		
		if (idx1 < annoName.length)
			gOffScreenGraphics.drawString(annoName[idx1], 10, 20);
		else
			gOffScreenGraphics.drawString("annotatation is done!", 10, 50);
		
		// draw the current line
		for (int i = 0; i < idx2; i += 2) {
			gOffScreenGraphics.drawLine(xPoints[idx1][i], yPoints[idx1][i],
					xPoints[idx1][i + 1], yPoints[idx1][i + 1]);
		}

		// draw the pre lines
		gOffScreenGraphics.setColor(Color.GREEN);
		for (int i = 0; i < idx1 && i < annoName.length; i++) 
			for(int j = 0; j < numXY; j += 2) {
			// gOffScreenGraphics.drawLine(xPoints[i][j], yPoints[i][j], xPoints[i][j + 1], yPoints[i][j + 1]);
			// gOffScreenGraphics.drawOval(xPoints[i][j], yPoints[i][j], _circleLen, _circleLen);
			// gOffScreenGraphics.drawOval(xPoints[i][j + 1], yPoints[i][j + 1], _circleLen, _circleLen);
			
			// gOffScreenGraphics.fillOval(xPoints[i][j], yPoints[i][j], _circleLen, _circleLen);
			// gOffScreenGraphics.fillOval(xPoints[i][j + 1], yPoints[i][j + 1], _circleLen, _circleLen);
			if(j < 1) {
				gOffScreenGraphics.drawLine(xPoints[i][j], yPoints[i][j], xPoints[i][j + 1], yPoints[i][j + 1]);
			} else {
				gOffScreenGraphics.fillOval(xPoints[i][j], yPoints[i][j], _circleLen, _circleLen);
				gOffScreenGraphics.fillOval(xPoints[i][j + 1], yPoints[i][j + 1], _circleLen, _circleLen);
			}
		}
			
		// paint(gOffScreen);
		g.drawImage(offScreenImage, _startJframeX, _startJframeY, this);
		g.dispose();
	}

	@Override
	public void paint(Graphics g) {
		update(g);
	}

	@Override
	public void dragEnter(DropTargetDragEvent dtde) {
	}

	@Override
	public void dragOver(DropTargetDragEvent dtde) {
	}

	@Override
	public void dropActionChanged(DropTargetDragEvent dtde) {
	}

	@Override
	public void dragExit(DropTargetEvent dte) {
	}
	
	// drop the images into UI
	// get the image file list
	@SuppressWarnings("rawtypes")
	@Override
	public void drop(DropTargetDropEvent dtde) {
		try {
			if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
				dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
				
				List list = (List) (dtde.getTransferable()
						.getTransferData(DataFlavor.javaFileListFlavor));
				
				Iterator iterator = list.iterator();
				file_list.clear();
				curFileIdx = -1;
				
				while (iterator.hasNext()) {
					File file = (File) iterator.next();
					if (file.isDirectory()) {
						addFileToQueue(file);
					} else {
						if (file.getName().endsWith(".jpg") || file.getName().endsWith(".png"))
							file_list.add(file);
					}
				}
				
				setNextPic(1);
				dtde.dropComplete(true);
			} else {
				dtde.rejectDrop();
			}
		} catch (Exception e) {
			e.printStackTrace();
			dtde.rejectDrop();
			JOptionPane.showMessageDialog(this, "Failed to open image");
		}
	}
		
	// flag == 0 -- previous pic
	// flag == 1 -- next pic
	private void setNextPic(int flag) {
		int tmp = curFileIdx;

		if (flag == 0) {
			if (curFileIdx == 0) {
				JOptionPane.showMessageDialog(this, "The first one!");
				return;
			}
			curFileIdx--;
		} else {
			curFileIdx++;
		}
		
		boolean ok = false;
		while (!ok) {
			try {
				if (curFileIdx >= file_list.size()) {
					curFileIdx = tmp;
					if (curFileIdx == -1)
						return;
					JOptionPane.showMessageDialog(this, "The last one!");
					return;
				}
				File file = file_list.get(curFileIdx);


				initImage = ImageIO.read(file);

				initImage = initImage.getScaledInstance(
						(int) (initImage.getWidth(null) * scale),
						(int) (initImage.getHeight(null) * scale),
						Image.SCALE_SMOOTH);		// SCALE_DEFAULT, SCALE_SMOOTH

				// path and fileName
				path     = file.getParent();
				fileName = file.getName();
				
				int imgLen = file_list.size();
				setTitle(imgLen + " images - " + fileName);

				int idx = fileName.lastIndexOf('.');
				if (idx != -1)
					fileName = fileName.substring(0, idx);

				idx1 = 0;
				idx2 = 0;
				
				// set default value
				Arrays.fill(isOccluded, 2);	// full occluded
				Arrays.fill(isDefault, 0);  // default
				Arrays.fill(points, 0);
				
				for (int i = 0; i < annoName.length; i++) {
					Arrays.fill(xPoints[i], 0);
					Arrays.fill(yPoints[i], 0);
				}
				
				setSize(initImage.getWidth(null)  + border * 3 + _startJframeX,
						initImage.getHeight(null) + border * 3 + _startJframeY
						);

				// readAnnotation(path + "/Annotations/" + fileName + ".xml");
				repaint();

				ok = true;

			} catch (Exception e) {
				e.printStackTrace();
				if (flag == 0) {
					if (curFileIdx == 0) {
						return;
					}
					curFileIdx--;
				} else {
					curFileIdx++;
				}
			}
		}
	}
	
	private void addFileToQueue(File folder) {
		for (File file : folder.listFiles()) {
			if (file.isDirectory())
				addFileToQueue(file);
			else
				if (file.getName().endsWith(".jpg") || file.getName().endsWith(".png"))
					file_list.add(file);
		}
	}
	
	private boolean readAnnotation(String path) {
		File gt = new File(path);
		if (!gt.exists())
			return false;

		int choice = JOptionPane.showConfirmDialog(this,
				"Annotation file is found, read it or not?", "tips",
				JOptionPane.YES_NO_OPTION);
		if (choice != JOptionPane.YES_OPTION)
			return false;

		try {
		} catch (Exception e) {
			e.printStackTrace();
			idx1 = 0;
			idx2 = 0;
			for (int i = 0; i < 6; i++) {
				Arrays.fill(xPoints[i], 0);
				Arrays.fill(yPoints[i], 0);
			}
			JOptionPane.showMessageDialog(this, "Invalid annotation file");
		}
		return true;
	}

	public static void main(String[] args) {
		new DatasetAnnotated_BB_Occ();
	}

}


你可能感兴趣的:(annotation,human,Pose,estimatio)