利用神经网络算法的C#手写数字识别
作者:CQITer小编 时间:2018-02-21 16:03

下载Demo - 2.77 MB (原始地址)
handwritten_character_recognition.zip
下载源码 - 70.64 KB (原始地址)
nnhandwrittencharreccssource.zip
介绍
这是一篇基于Mike O'Neill 写的一篇很棒的文章:神经网络的手写字符识别(Neural Network for Recognition of Handwritten Digits)而给出的一个人工神经网络实现手写字符识别的例子。尽管在过去几年已经有许多系统和分类算法被提出,但是手写识别任然是模式识别中的一项挑战。Mike O'Neill的程序对想学习通过神经网络算法实现一般手写识别的程序员来说是一个极好的例子,尤其是在神经网络的卷积部分。那个程序是用MFC/ C++编写的,对于不熟悉的人来说有些困难。所以,我决定用C#重新写一下我的一些程序。我的程序已经取得了良好的效果,但还并不优秀(在收敛速度,错误率等方面)。但这次仅仅是程序的基础,目的是帮助理解神经网络,所以它比较混乱,有重构的必要。我一直在试把它作为一个库的方式重建,那将会很灵活,很简单地通过一个INI文件来改变参数。希望有一天我能取得预期的效果。
字符检测
模式检测和字符候选检测是我在程序中必须面对的最重要的问题之一。事实上,我不仅仅想利用另一种编程语言重新完成Mike的程序,而且我还想识别文档图片中的字符。有一些研究提出了我在互联网上发现的非常好的目标检测算法,但是对于像我这样的业余项目来说,它们太复杂了。在教我女儿绘画时发现的一个方法解决了这个问题。当然,它仍然有局限性,但在第一次测试中就超出了我的预期。在正常情况下,字符候选检测分为行检测,字检测和字符检测几种,分别采用不同的算法。我的做法和这有一点点不同。检测使用相同的算法:
public static Rectangle GetPatternRectangeBoundary
(Bitmap original,int colorIndex, int hStep, int vStep, bool bTopStart)
以及:
public static List<Rectangle> PatternRectangeBoundaryList
(Bitmap original, int colorIndex, int hStep, int vStep,
bool bTopStart,int widthMin,int heightMin)
通过改变参数hStep (水平步进)和vStep (垂直步进)可以简单地检测行,字或字符。矩形边界也可以通过更改bTopStart 为true 或false实现从上到下和从左到右不同方式进行检测。矩形被widthMin 和d限制。我的算法的最大优点是:它可以检测不在同一行的字或字符串。


字符候选识别可以通过以下方法实现:
public void PatternRecognitionThread(Bitmap bitmap)
{
_originalBitmap = bitmap;
if (_rowList == null)
{
_rowList = AForge.Imaging.Image.PatternRectangeBoundaryList
(_originalBitmap,255, 30, 1, true, 5, 5);
_irowIndex = 0;
}
foreach(Rectangle rowRect in _rowList)
{
_currentRow = AForge.Imaging.ImageResize.ImageCrop
(_originalBitmap, rowRect);
if (_iwordIndex == 0)
{



