[置顶] java实现基于Mnist数据集的手写数字识别
2018-02-06 11:29
926 查看
最近空下来学习了简单的图像识别基础,做了这个算是一个小入门吧,就当为之后的毕设铺铺路了。这个原理实现起来很简单,我用的是20*20大小的图片,主要就是将待识别图片的400个像素的灰度值提取出来与训练样本进行比对,找到灰度值相减绝对值最小的样本,即为待识别图片的数字值,效果如下:
接下来就一步一步的来实现这个小程序。
页面采用一个大的Jpanel,一个顶部菜单JMenuBar操作,菜单中包含三个小菜单JMenuItem,分别为识别,加载图像,退出
在大的Jpanel里面有一个小的Jpanel,用来刷新加载图片,右侧有一个JButton,实现识别功能,下方JLabel为识别结果
下面来具体实现代码部分
这里要说明一下,训练数据分为两部分,一部分就是5000张手写的数字图片,另一部分是5000张图片的灰度值,由第一部分提取出来的csv格式的数据,每条数据包含401个内容,分别为本条数据代表的数字以及400个像素的灰度值,可以用Excel打开如下图
接下来就一步一步的来实现这个小程序。
一、外观设计
外观主要是采用java的WindowBuilder,如果没有的话可以去下一个http://www.eclipse.org/windowbuilder/download.php,具体如何安装这里就不做介绍了。页面采用一个大的Jpanel,一个顶部菜单JMenuBar操作,菜单中包含三个小菜单JMenuItem,分别为识别,加载图像,退出
在大的Jpanel里面有一个小的Jpanel,用来刷新加载图片,右侧有一个JButton,实现识别功能,下方JLabel为识别结果
下面来具体实现代码部分
(1)顶部菜单
setTitle("数字识别"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭按钮 setResizable(false);//不能修改窗口大小 setBounds(0,0,600,600); JMenuBar menuBar = new JMenuBar();//绑定菜单栏 setJMenuBar(menuBar); JMenu menu = new JMenu("操作"); menuBar.add(menu);//加入操作菜单 JMenuItem importItem = new JMenuItem("加载图片"); JMenuItem serach = new JMenuItem("识别"); JMenuItem exit = new JMenuItem("退出"); menu.add(importItem); menu.add(serach); menu.add(exit);
(2)主面板
contentPane = new JPanel();//加入面板 contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(null); JLabel label = new JLabel("识别结果:"); label.setBounds(10,450,97,15); contentPane.add(label); JLabel result = new JLabel(""); result.setBounds(90,450,97,15); contentPane.add(result); JButton button = new JButton("识别"); button.setBounds(450, 300, 100, 25); contentPane.add(button);
(3)图片面板
imagePanel viewPanel = new imagePanel(); viewPanel.setBounds(10, 10, 300, 300);//280 contentPane.add(viewPanel);//添加到主面板
(4)加载图片
/* * 面板,预览加载图片 */ public class imagePanel extends JPanel{ private Image image; public imagePanel() { setLayout(null); } public void loadImage(BufferedImage src){ image = src.getScaledInstance(300, 300, Image.SCALE_SMOOTH);//创建缩略图400*400 280 repaint(); } @Overrid 4000 e public void paint(Graphics g) { //如何重绘面板 if (image != null) { //清除上次加载的图片 g.clearRect(0, 0, getWidth(), getHeight()); g.drawImage(image, 0, 0, this); } } }
(5)监听事件
/* * 加入点击事件监听器 */ importItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("加载"); JFileChooser chooser =new JFileChooser(); int result = chooser.showDialog(null, "导入图片"); if(result == 0){ file = chooser.getSelectedFile(); try { BufferedImage src = ImageIO.read(file); viewPanel.loadImage(src);//将图片重新绘制 } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } System.out.println(result); } }); /* * 加载训练数据 */ DistinguishUtil distinguishUtil = new DistinguishUtil(); distinguishUtil.loadData(new File("traindata2.csv")); setTitle("数字图像识别---加载数据完成"); serach.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("识别"); String resultString = distinguishUtil.distinguish(file); result.setText(resultString); } }); exit.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("退出"); } }); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("按钮"); String resultString = distinguishUtil.distinguish(file); result.setText(resultString); } });
二、数据处理
(1)获取图片的灰度特征值
public int[] getDigest(File targetImage) throws IOException{ BufferedImage image = ImageIO.read(targetImage); int[] digest = new int[image.getHeight()*image.getWidth()]; image.getRGB(0, 0, image.getWidth(), image.getHeight(), digest, 0, image.getWidth());//将灰度特征值保存进数组 //255 -(r*30 + g*59 + b*11)/100 for (int i = 0; i < digest.length; i++) { int color = digest[i]; int r = color << 8 >>> 24; int g = color << 16 >>> 24; int b = color << 24 >>> 24; int gray = 255 -(r*30 + g*59 + b*11)/100; digest[i] = gray; } return digest; }
(2)数据对象
/* * 该类的一个对象封装一条数据 */ public class trainData { private String targetString;//识别结果 private int[] digestString;//长度为28*28的灰度特征值 public String getTargetString() { return targetString; } public void setTargetString(String targetString) { this.targetString = targetString; } public int[] getDigestString() { return digestString; } public void setDigestString(int[] digestString) { this.digestString = digestString; } }
(3)加载训练数据
ExcelUtil util = new ExcelUtil(); try { for(int i = 0; i <= 1200 ; i++){ int[] dataInt = util.readRdx(i+1); String target = util.readTarget(i+1); trainData traindata = new trainData(); traindata.setDigestString(dataInt); traindata.setTargetString(target); datas.add(traindata); } } catch (EncryptedDocumentException e) { e.printStackTrace(); } catch (InvalidFormatException e) { e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }
(4)比对数据
public String distinguish(File targetImage) { int[] digest; int index = 0; try { digest = getDigest(targetImage); if (digest != null) { int minDif = getDif(digest, datas.get(0).getDigestString());//与第一个训练数据集进行比对 for (int i = 1; i < datas.size(); i++) { int dif = getDif(digest, datas.get(i).getDigestString()); if(dif < minDif){ minDif = dif; index = i; } } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return datas.get(index).getTargetString(); }
//获取特征值差值 public int getDif(int[] imageDigest,int[] trainingDigest){ int dif = 0; for (int i = 0; i < trainingDigest.length; i++) { dif += Math.abs((imageDigest[i]-trainingDigest[i])); } return dif; }
这里要说明一下,训练数据分为两部分,一部分就是5000张手写的数字图片,另一部分是5000张图片的灰度值,由第一部分提取出来的csv格式的数据,每条数据包含401个内容,分别为本条数据代表的数字以及400个像素的灰度值,可以用Excel打开如下图
欢迎大家随时批评指正,一起交流学习,可以加我q 504334357
相关文章推荐
- 利用tensorflow一步一步实现基于MNIST 数据集进行手写数字识别的神经网络,逻辑回归
- 神经网络与深度学习 使用Python实现基于梯度下降算法的神经网络和自制仿MNIST数据集的手写数字分类可视化程序 web版本
- 神经网络与深度学习 1.6 使用Python实现基于梯度下降算法的神经网络和MNIST数据集的手写数字分类程序
- TensorFlow学习笔记(3)--实现Softmax逻辑回归识别手写数字(MNIST数据集)
- tensorflow 学习专栏(五):在mnist数据集上使用tensorflow实现临近算法(Nearest-Neighbor)进行手写数字识别
- Kaggle Digit Recognizer 基于sklearn实现的手写数字识别 for MNIST data
- 第二课 深度学习的“hello world”——基于mnist数据集的手写数字识别
- TF之RNN:基于顺序的RNN分类案例对手写数字图片mnist数据集实现高精度预测—Jason niu
- TensorFlow实现机器学习的“Hello World”--Mnist手写数字识别
- Tensorflow 实现 MNIST 手写数字识别
- 手写数字识别(二)----SVM 实现Mnist-image 手写数字图像识别
- Neural Network实战:Java实现Back Propagation算法 + 手写数字识别
- TensorFlow学习-基于CNN实现手写数字识别
- 基于K-近邻算法识别手写数字的实现
- 基于tensorflow的MNIST手写数字识别(三)--神经网络篇
- [置顶] Caffe学习笔记(六):mnist手写数字识别训练实例
- 神经网络实现手写数字识别(MNIST)
- 基于tensorflow的MNIST手写数字识别--入门篇
- 【Python | TensorBoard】用 PCA 可视化 MNIST 手写数字识别数据集
- Random Forest实战:Java实现 + 手写数字识别