现在的位置: 首页 > 综合 > 正文

手写识别1

2018年02月20日 ⁄ 综合 ⁄ 共 2068字 ⁄ 字号 评论关闭

最近想自己写个手写识别的小程序,然后又可能的话再试试数学公式识别什么的,所以周末腾出时间写了些代码。

照例先在网上找了找有没有现成的实现,发现了这篇文章http://blog.csdn.net/hellogv/article/details/5526284。把博主的代码下载下来,调试了一下,发现基本功能实现了,但是性能很一般,决定在此代码的基础上继续我的工作。

上面文章中的代码只是简单的比对当前输入与训练样本中特征的相似程度,取一个最大的作为分类结果,多少有些简单。

最朴素的手写识别想法是在一个规定大小的区域内,比如20X20的像素区域内,进行神经网络的训练,那么这个网络的输入层就有400个,还要加上一个常数,一共401个。然后设置一个隐藏层,输出层一个节点就成。将标记过的手写样本输入到网络中,不断优化参数,得到一个字符的神经网络。

同时,还有一些手写识别结合了笔画顺序与种类来辅助分类,为了后续工作的开展,我先补充了记录笔画的代码部分。

当前使用的手写输入设备是鼠标,图像的大小为40X40。为了记录笔画顺序,在源代码中加入了MouseDown和MouseUp两个时间的响应,并修改了MouseMove的响应,代码如下:

privatevoid pbDraw_MouseDown(object sender, MouseEventArgs e)

{

       mouse_hit= true;

       if (clear_hit == 0)

       {

              mousehit.Push(0);

                clear_hit++;

       }

}

 

privatevoid pbDraw_MouseUp(object sender, MouseEventArgs e)

{

       if(mouse_hit == true)

       {

              int count = mousehit.Peek();

                StreamWriter sw = newStreamWriter(mg_fn, true);

                Point p1;

                sw.WriteLine(count);

                while (mouseGesture.Count != 0)

                {

                    p1 = mouseGesture.Peek();

                    sw.WriteLine(p1.X +"?" + p1.Y);

                    mouseGesture.Dequeue();

                }

                sw.Close();

                count++;

                mousehit.Push(count);

       }

       mouse_hit= false;

}

 

privatevoid pbDraw_MouseMove(object sender, MouseEventArgs e)

{

       if(mouse_hit == true)

       {

                Point p1 = new Point { X = e.X,Y  = e.Y};

               clsHandWrite.Draw(e.X, e.Y);

                mouseGesture.Enqueue(p1);

       }

}

其中mouse_hit表示鼠标键是否被按下,true表示按下,false表示释放。

clear_hit表示界面上的clear按钮是否被按过,该按钮每被按一次,代表一次训练或识别结束,将笔画计数器count清零。(这算是一个我的程序的一个假设吧,这个触发关系以后还应该妥善处理一下,同时记录笔画的栈mousehit也应该随着清空,避免溢出。)

每次鼠标键按下开始,到鼠标键释放为止,记录中间鼠标滑过的坐标点,记录在mouseGesture中。鼠标键释放后将mouseGesture中的点信息存入临时文件mg_fn.txt中。

在主程序中加入一个将当前笔画转为字符串的函数,同时修改Learn函数如下:

privateString GetCurrentMouseGesture()

{

       Stringtmp = "";

       StreamReadersr = new StreamReader(mg_fn, true);

       while(!sr.EndOfStream)

       {

              tmp= tmp+ sr.ReadLine() + "!" ;

       }

       sr.Close();

       returntmp;

}

 

publicvoid Learn(String name)

{

       Stringmgrec = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase +"mgrec.txt";

       StreamWritersw = new StreamWriter(fileName, true);

       StreamWritersw_mg = new StreamWriter(mgrec, true);

       sw.WriteLine(name+ " " + GetBMPContext(bmpDraw));

       sw_mg.WriteLine(name+ " " + GetCurrentMouseGesture());

       sw.Close();

       sw_mg.Close();

}

为了保持和原特征文件处理的一致性,加入了函数GetCurrentMouseGesture,用于将当前的笔画顺序转成字符串,其中mg_fn文件中行与行用"!"隔开,每组坐标的两个数用“?”隔开。

这样基本工作就完成了。

下面要做的就是引入机器学习的相关内容,建立神经网络学习,提高分类的准确性。

待续

抱歉!评论已关闭.