• 手写识别


    作者:倪屁屁
    链接:https://zhuanlan.zhihu.com/p/40431290
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    (1)KNN分类算法

    KNN是通过测量不同特征值之间的距离进行分类。如果取样本的特征空间里K个相似对象向里占最多的类别,并把样本归入此类。

    理解:通过计算样本与待计算对象之间的差距 dn(距离) 让样本以对象为中心开始排队,取以个最大半径K,在这个范围里,那一类的类占的比重大,就把待测对象标记为该类。

    *有一点像soul交友软件,通过你的信息,在数据库里计算和你相似距离最小的用户,并且还会给你表明你们的相似度,然后把你也归入这一类星球里*

    (2)KNN使用

    将数据转化为可计算数据,并且储存到相应文件里。

    (0)录入样本

    (1) 录入带识别对象

    (2) 计算样本数据和识别对象的距离;

    (3)按照距离大小把对象存储到队列里

    (4)取得K值计算K值内类别所占的最多类为最相似类别;

    (5)将待识别样本标记为最相似类别

    二--思路二

    1.首先录取样本的数据,得到0-9这10个数字对应的数据类,着10个数字对应着你输入的数据,输入的数据越多越好

    *1这里我用一个数组存“0-9”着是10个数字,想让数组对应的值为样本的个数,最开始都初始化为0,当你准备录入“0”的时候,就在文件夹里建立0的第1个样本,并且a[0]++;这样号访问到底有多少个“0”数据,也好到后期算距离;

    2.读取样本数据----a[10]++;"待测量数据增多"

    3. 用样本数据分别和 "0-9”着10个类里面存的样本算距离,取得平均距,并且当作样本与“0”到“9”着9个数字之间的差距,取最小距离mind ,以及对应最相似数字

    4.将待测对象的类别修改为最相似类

    我会调用一个方法,直接把待测对像的数据放到,相似数字的会便利的下一个数据,并且a[相似数字]++

    public class MyUI extends JFrame {
    	public Hashtable<Integer,String> ht=new Hashtable<Integer,String>();
    	private int width = 400;
    	private int height = 550;
    	 MyCanvas canvas = null;
    	private Graphics g;
    	public JTextField number=null;
    	public static void main(String[] args) throws AWTException {
    		MyUI myui=new MyUI();
    		
    		}
    	
    	public MyUI()
    	{
    		super();
    		this.setTitle("handwirting");
    		this.setSize(width, height);
    		this.setResizable(false);
    		this.setLocation(400, 180);
    		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		this.setLayout(null);
    		this.canvas = new MyCanvas(this);
    		this.add(canvas);
    		
    		JPanel jp=new JPanel();
    		jp.setBackground(Color.BLACK);
    		jp.setSize(new Dimension(400,40 ));
    		this.add(BorderLayout.EAST,jp);
    		jp.setLayout(new FlowLayout());
    		JButton b1=new JButton("练习");
    		b1.addActionListener(canvas);
    		JButton b2=new JButton("识别");
    		b2.addActionListener(canvas);
    		
    		jp.add(b1);
    		jp.add(b2);
    		number=new JTextField(1);
    		
    		jp.add(number);
    		this.setVisible(true);
    		
    		canvas.setG();
    	
    	}
    
    }
    

    首先会有这么一个界面,在输入框里写入要学习的数字(存储相应对象的数据1),这时候我会将这个黑色区域存下来,并且获取它的每一个点rgb因为是黑白的,所以就将白色设为1,黑色设为0,这几样就可以得到一串子,把他存到名字为“0-1”文件里代表“0”数字的第一组数据。

    我会配合着输出存储情况

    第一行代表计算机要学习“存储”的类别

    第二行是当前对10个数组存储数据的情况,目前只学习了1所以[1]的长度就是1啦;

    这里[10]用来代表待识别的对象。

    这时候点击识别按钮,进行识别

    这里就是输出

    我这个版本就是有bug的

    进行改进

    (1)需要如果计算出来的差距特别大的时候,就直接选择废除这个数据,并且输出不能识别

    (2)每一次启动程序都需要重新输入学习样本的数据,应该调用一个方法来实践设置数组的长度,在计算knn时候直接读取以前存取的数据。。。。。

    //图片存储

    public void wirte2jpg(int key) throws IOException {
    
    		// TODO Auto-generated method stub
    		Dimension imagesize = this.getSize();
    		// 创建一个图形
    		BufferedImage image = new BufferedImage(imagesize.width, imagesize.height, BufferedImage.TYPE_INT_RGB);
    		Graphics graphics = image.createGraphics();
    		this.paint(graphics);
    		// 创建图片
    		File f = new File("D:手写图片\" + key + "-" + (keylength[key]) + ".jpg");
    		try {
    			if (!f.exists()) {
    				f.createNewFile();
    				System.out.println(123);
    			}
    			// 存储一张手写图片
    			ImageIO.write(image, "jpg", f);
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		savepage(image, key);
    		this.setBackground(Color.BLACK);
    		
    	}
    

    //存储数据

    	public void savepage(BufferedImage image, int key) throws IOException {
    		int k = 0;
    		// 存起来图像
    		for (int i = image.getMinY(); i < image.getMinY() + height; i++) {
    			for (int j = image.getMinX(); j < image.getMinX() + width; j++) {
    				// 数组颜色
    				int mycolor = image.getRGB(j, i);
    				if (mycolor == -1) {
    					Mydata[k] = 1;
    					k++;
    				} else {
    					Mydata[k] = 0;
    					k++;
    				}
    			}
    		}
    
    		// 创建文本本舰存数组
    		File f = new File("D:数字\" + key + "-" + (keylength[key]) + ".txt");
    		FileOutputStream out = null;
    		try {
    			out = new FileOutputStream(f);
    		} catch (FileNotFoundException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		// 存入数据
    		for (int q = 0; q < SIZE; q++) {
    			try {
    				out.write((byte) Mydata[q]);
    			} catch (IOException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    

    总结一下-这个项目我耗费最久的在IO流,以及数据存储上面,以及方法之间的调用布局,

    方法与方法之间的调用关系,存储数据的读取上面。下一篇总结IO流以及异常。

  • 相关阅读:
    网络流24题-[CTSC1999]家园
    网络流24题-孤岛营救问题
    汽车加油行驶问题(分层图最短路)
    送外卖(可重复点的哈密顿路径)
    信与信封问题
    最小完全图(最小生成树加边成完全图)
    校园网(有向图加边变成强连通图)
    玩具装箱
    MSTest、NUnit、xUnit对照表
    .NET Core学习 笔记索引
  • 原文地址:https://www.cnblogs.com/ttnrt/p/11086572.html
Copyright © 2020-2023  润新知