算法组:手写数字识别
我在比赛中主要负责的是用java语言进行识别平台界面的搭建以及与Python的连接,所以关于算法如何实现和图像如何处理在这里不做总结。界面的具体功能总结起来就是画板写数字,上传图片并显示。我们组做了两个界面,Swing界面和网页界面。下面分别地详细作结:
Swing界面:
主界面设计
public class Interface extends JFrame {
private drawlistener dl;
private Graphics g;
JFrame frame=new JFrame();
public void Interface() {
frame.setTitle("手写数字识别"); //设置窗体名称
frame.setSize(600, 520); //设置窗体大小
frame.setDefaultCloseOperation(3); //用System exit 方法退出应用程序
frame.setLocationRelativeTo(null); //窗体居中
FlowLayout layout = new FlowLayout(FlowLayout.LEFT); //流式布局左对齐
frame.setLayout(layout); //窗体使用流式布局管理器
frame.setResizable(false); //窗体大小不变
更改鼠标样式
String url = "images/小手.png";
Toolkit tk = Toolkit.getDefaultToolkit();
Image image = new ImageIcon(url).getImage();
Cursor cursor = tk.createCustomCursor(image, new Point(10, 10), "norm");
frame.setCursor(cursor);
//使用数组保存按钮名
String buttonName[] = {"画笔","橡皮", "重置","图片","确定"};
//用于保存图形按钮,使用网格布局
JPanel jp1=new JPanel(new GridLayout(5, 2,20,20));
jp1.setPreferredSize(new Dimension(150, 400));
dl=new drawlistener(frame);
//循环为按钮面板添加按钮
for (int i = 0; i < buttonName.length; i++) {
JButton jbutton = new JButton(buttonName[i]);
jbutton.addActionListener(dl); //为按钮添加监听
jp1.add(jbutton);
}
JPanel jp2=new JPanel();//画布面板
jp2.setPreferredSize(new Dimension(420, 420));
jp2.setBackground(Color.WHITE);
// 定义Color数组,用来存储按钮上要显示的颜色信息
Color[] colorArray = { Color.BLUE, Color.GREEN, Color.RED,
Color.BLACK,Color.ORANGE,Color.PINK,Color.CYAN,
Color.MAGENTA,Color.DARK_GRAY,Color.GRAY,
Color.LIGHT_GRAY,Color.YELLOW};
//用于保存颜色按钮的面板
JPanel jp3=new JPanel(new GridLayout(1,colorArray.length,15,3));
// 循环遍历colorArray数组,根据数组中的元素来实例化按钮对象
for (int i = 0; i < colorArray.length; i++) {
JButton button = new JButton();
button.setBackground(colorArray[i]);
button.setPreferredSize(new Dimension(30, 30));
button.addActionListener(dl); //为按钮添加监听
jp3.add(button);
}
//将面板添加到主窗体
frame.add(jp1);
frame.add(jp2);
frame.add(jp3);
//添加按钮,作为当前颜色
JButton nowColor=new JButton();
nowColor.setPreferredSize(new Dimension(45,45));
nowColor.setBackground(Color.BLACK); //默认黑色
frame.add(nowColor);
//设置窗体的组件可见,如果为FALSE就看不到任何组件
frame.setVisible(true);
//获取画笔对象
g=jp2.getGraphics();
dl.setG(g);
dl.setNowColor(nowColor);
//为面板添加鼠标监听,用于绘制图形
jp2.addMouseListener(dl); //普通监听
jp2.addMouseMotionListener(dl); //拖动监听
}
处理鼠标监听
JFrame frame=new JFrame(); private Color color; //颜色属性 private Graphics g; //画笔属性 private String str; //保存按钮上的字符串,区分不同的按钮 private int x1,y1,x2,y2; //(x1,y1),(x2,y2)分别为鼠标的按下和释放时的坐标 private JButton nowColor; //当前颜色按钮 static private int i = 905; private String dir = "group"; public drawlistener(JFrame frame) { this.frame=frame; } //获取Draw类的画笔对象 public void setG(Graphics g) { this.g = g; } //获取当前颜色按钮 public void setNowColor(JButton nowColor) { this.nowColor = nowColor; } //鼠标拖动的方法 public void mouseDragged(MouseEvent e) { //画线的方法 if ("画笔".equals(str)) { int x, y; x = e.getX(); y = e.getY(); float lineWidth = 20.0f; ((Graphics2D)g).setStroke(new BasicStroke(lineWidth)); g.drawLine(x, y, x1, y1); x1 = x; y1 = y; } if ("橡皮".equals(str)) { int x, y; x = e.getX(); y = e.getY(); float lineWidth = 30.0f; ((Graphics2D)g).setStroke(new BasicStroke(lineWidth)); g.setColor(color.WHITE); g.drawLine(x, y, x1, y1); x1 = x; y1 = y; } } //鼠标按下方法 public void mousePressed(MouseEvent e) { g.setColor(color);//改变画笔的颜色 x1=e.getX();//获取按下时鼠标的x坐标 y1=e.getY();//获取按下时鼠标的y坐标 } //鼠标释放方法 public void mouseReleased(MouseEvent e) { x2=e.getX();//获取释放时鼠标的x坐标 y2=e.getY();//获取释放时鼠标的y坐标 } //鼠标进入方法 public void mouseEntered(MouseEvent e) { if ("画笔".equals(str)) { String url = "images/画笔.png"; //储存鼠标图片的位置 Toolkit tk = Toolkit.getDefaultToolkit(); Image image = new ImageIcon(url).getImage(); Cursor cursor = tk.createCustomCursor(image, new Point(10, 10), "norm"); frame.setCursor(cursor);} if ("橡皮".equals(str)) { String url = "images/橡皮.png"; //储存鼠标图片的位置 Toolkit tk = Toolkit.getDefaultToolkit(); Image image = new ImageIcon(url).getImage(); Cursor cursor = tk.createCustomCursor(image, new Point(10, 10), "norm"); frame.setCursor(cursor);} } //鼠标退出方法 public void mouseExited(MouseEvent e) { //设置鼠标样式 String url = "images/小手.png"; Toolkit tk = Toolkit.getDefaultToolkit(); Image image = new ImageIcon(url).getImage(); Cursor cursor = tk.createCustomCursor(image, new Point(10, 10), "norm"); frame.setCursor(cursor); }
处理按钮监听
public void actionPerformed(ActionEvent e) { //判断是颜色按钮还是图形按钮 if ("".equals(e.getActionCommand())) { JButton jb = (JButton) e.getSource(); color = jb.getBackground(); nowColor.setBackground(color);//处理当前颜色 } else { str = e.getActionCommand(); if ("重置".equals(str)) { g.setColor(color.WHITE); float lineWidth = 600.0f; ((Graphics2D)g).setStroke(new BasicStroke(lineWidth)); g.drawLine(0, 0, 420, 420); } if("确定".equals(str)) { try { saveFile(); } catch (IOException e1) { e1.printStackTrace(); } } if("图片".equals(str)) { deleteDirectory(dir); showPicture(); } } }
几个小功能实现的函数
- 删除文件
public void deleteDirectory(String dir) { File dirFile = new File(dir); // 删除文件夹中的所有文件包括子目录 File[] files = dirFile.listFiles(); for (int i = 0; i < files.length; i++) { // 删除子文件 if (files[i].isFile()) { deleteFile(files[i].getAbsolutePath()); } // 删除子目录 else if (files[i].isDirectory()) { deleteDirectory(files[i].getAbsolutePath()); } } } public void deleteFile(String fileName) { File file = new File(fileName); // 如果文件路径所对应的文件存在,并且是一个文件,则直接删除 if (file.exists() && file.isFile()) { file.delete(); } }
- 截图并保存图片
try { Robot robot = new Robot(); BufferedImage bi = robot.createScreenCapture(new Rectangle(823,293,420,420)); FileOutputStream out = new FileOutputStream("image\\image1.png"); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); encoder.encode(bi); } catch (AWTException e1) { e1.printStackTrace(); }
- 选择文件并复制到另一个文件夹下
chooser = new JFileChooser(); chooser.setCurrentDirectory(new File("test")); chooser.showOpenDialog(null); String name = chooser.getSelectedFile().getPath(); copypicture(name); public void copypicture(String oldpath) { try { File temp = new File(oldpath); FileOutputStream output; FileInputStream input = new FileInputStream(temp); output = new FileOutputStream(newpath); byte[] b = new byte[1024 * 5]; int len; while ((len = input.read(b)) != -1) { output.write(b, 0, len); } output.flush(); output.close(); input.close(); } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } }
- java调用python
Process proc = null; try { proc = Runtime.getRuntime().exec("python "+PY_URL); proc.waitFor(); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); }
- 读文件内容
BufferedReader br; String answer = null; br = new BufferedReader(new FileReader(new File(DATA_SWAP))); answer = br.readLine();
网页界面:
网页部分是另一个队友做的,这里只是简单的展示一下。经过这次比赛,感觉收获了很多。不仅仅是代码学习上的收获,更是对自己心智的历练。有时候调bug真的需要花费很多的时间和精力,而且情绪也时常会面临崩溃的境地。只希望自己在后来的代码学习中能够保持平和的内心,一直坚持下去,学到更多的东西。