Click here to Skip to main content
15,880,796 members
Articles / Artificial Intelligence / Neural Networks

Multiple convolution neural networks approach for online handwriting recognition

Rate me:
Please Sign up or sign in to vote.
4.95/5 (37 votes)
9 Apr 2013CPOL8 min read 75.6K   25.1K   74  
The research focuses on the presentation of word recognition technique for an online handwriting recognition system which uses multiple component neural networks (MCNN) as the exchangeable parts of the classifier.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ANN.Perceptron;
using UPImage;
using System.Drawing;
using System.Drawing.Imaging;
using ANN.Perceptron.ArchiveSerialization;
using System.Threading;
using System.Threading.Tasks;
using System.IO;
using SpellChecker;
namespace ANN.Perceptron.Network
{
    public class WordRecognition
    {
        #region Private Properties
        InputPattern wordPattern;
        private List<ConvolutionNetwork> networks;
        List<List<Char>> charMatrix;
        List<String> words;
        MultipleSpelling multiSpelling;
        #endregion

        #region Public Properties
        public InputPattern WordPattern
        {
            get
            {
                return wordPattern;
            }
            set
            {
                if (wordPattern == value)
                    return;
                wordPattern = value;
            }
        }
        public List<ConvolutionNetwork> Networks
        {
            get
            {
                return networks;
            }
            set
            {
                if (networks == value)
                    return;
                networks = value;
            }
        }
        #endregion

        #region constructors
        public WordRecognition(MultipleSpelling spelling)
        {
            networks = null;
            multiSpelling = spelling;
        }
        #endregion
        #region Private Methods
        private List<InputPattern> GetPatternsFromBitmap(InputPattern parentPattern, int hStep, int vStep, bool isTopStart, int minWidth, int minHeight)
        {
            List<InputPattern> patternlist = null;
            parentPattern.GetPatternBoundaries(hStep, vStep, isTopStart, minWidth, minHeight);
            if (parentPattern.PatternRects.Count > 0)
            {

                patternlist = new List<InputPattern>();
                foreach (var rect in parentPattern.PatternRects)
                {
                    Bitmap bmp = new Bitmap(rect.Width, rect.Height);
                    Graphics graph = Graphics.FromImage(bmp);
                    graph.DrawImage(parentPattern.OriginalBmp, 0, 0, rect, GraphicsUnit.Pixel);
                    int x = parentPattern.OriginalRectangle.X + rect.X;
                    int y = parentPattern.OriginalRectangle.Y + rect.Y;
                    Rectangle newRect = new Rectangle(x, y, rect.Width, rect.Height);
                    InputPattern childPattern = new InputPattern(bmp, 255, newRect);
                    patternlist.Add(childPattern);
                    graph.Dispose();
                }

            }

            return patternlist;
        }
        private bool PatternRecognition(Bitmap orginal, out List<Char> accChars)
        {
            bool isCharFound = false;
            accChars = new List<Char>();

            if (networks != null)
            {
                double ratio;
                int w;
                int h;
                Bitmap bm;
                int widthpad = 0;
                int heightpad = 0;
                if (orginal.Width > orginal.Height)
                {
                    ratio = (double)orginal.Width / 25;
                    w = 25;
                    h = (int)Math.Floor(orginal.Height / ratio);
                    bm = UPImage.ImageProcessing.ResizeBitmap(orginal, w, h);
                    widthpad = 4;
                    heightpad = 29 - h;
                }
                else
                {
                    ratio = (double)orginal.Height / 25;
                    h = 25;
                    w = (int)Math.Floor(orginal.Width / ratio);
                    bm = UPImage.ImageProcessing.ResizeBitmap(orginal, w, h);
                    widthpad = 29 - w;
                    heightpad = 4;
                }
                bm = UPImage.ImageProcessing.CreateColorPad(bm, Color.White, widthpad, heightpad);
                bm = UPImage.ImageProcessing.ColorToGrayscale(bm);
                byte[] imagedata = ImageProcessing.ConvertGrayscaleBitmaptoBytes(bm);


                foreach (var nw in networks)
                {
                    Char newChar = new Char();
                    PatternRecognition patterntest = new PatternRecognition(nw,null);
                    patterntest.ForwardpropagationThread(imagedata, bm.Width, bm.Height, out newChar);
                    if (newChar != nw.UnknownOuput && newChar!=new Char())
                    {
                        accChars.Add(newChar);
                    }
                }
                if (accChars.Count > 0)
                {
                    isCharFound = true;
                }
            }
            return isCharFound;
        }
        void GetWords(int startIndex, String baseWord)
        {
            String newWord = "";
            if (startIndex == charMatrix.Count - 1)
            {
                for (int i = 0; i < charMatrix[startIndex].Count; i++)
                {

                    newWord = String.Format("{0}{1}", baseWord, charMatrix[startIndex][i].ToString());
                    words.Add(newWord);

                }
            }
            else
            {
                for (int i = 0; i < charMatrix[startIndex].Count; i++)
                {
                    newWord = String.Format("{0}{1}", baseWord, charMatrix[startIndex][i].ToString());
                    int newIndex = startIndex + 1;
                    GetWords(newIndex, newWord);
                }
            }
        }
        #endregion
        #region Public methods
        public bool LoadTrainedParametersFiles(String[] FileNames)
        {
            
            bool result = false;
            try
            {
                
                // Read the files
                if (networks != null)
                {
                    networks.Clear();
                    networks = null;
                }
                Task task = Task.Factory.StartNew(() =>
                {
                    networks = new List<ConvolutionNetwork>();
                    foreach (String file in FileNames)
                    {
                        // Create a PictureBox.
                        try
                        {
                            ConvolutionNetwork nw = new ConvolutionNetwork();
                            var fsIn = new StreamReader(file);
                            var arIn = new Archive(fsIn.BaseStream, ArchiveOp.load);
                            nw.Serialize(arIn);
                            fsIn.Close();
                            networks.Add(nw);
                        }
                        catch (Exception ex)
                        {

                            result = false;
                        }
                    }
                });
                task.Wait();
                result = true;
                
            }
            catch(Exception ex)
            {
            
            }
            return result;
        }
        public String GetBestRecognizedWord(InputPattern wordPattern)
        {
            String st="";
            //get character patterns
            List<InputPattern> characterPatterns = GetPatternsFromBitmap(wordPattern, 10, 10, false, 10, 10);
            if (characterPatterns != null)
            {
                charMatrix = new List<List<char>>();
                //recognize character patterns and save them to character matrix
                foreach (var pt in characterPatterns)
                {
                    List<Char> charList = null;
                    PatternRecognition(pt.OriginalBmp,out charList);
                    if (charList.Count > 0)
                    {
                        charMatrix.Add(charList);
                    }
                }
                //get best word
                if (charMatrix.Count > 0)
                {
                    if (words != null)
                    {
                        words = null;
                    }
                    words = new List<string>();
                    GetWords(0, "");
                    if (words.Count > 0)
                    { 
                        //get best word
                        bool isCorrectedWord = false;
                        foreach (String wd in words)
                        {
                            if (wd.Length > 1)
                            {
                                if (multiSpelling.TestWord(wd))
                                {
                                    st = wd;
                                    isCorrectedWord = true;
                                    break;
                                }
                            }
                        }
                        if (!isCorrectedWord)
                        {
                            bool foundSimilarWord = false;
                            foreach (var wd in words)
                            {
                                if (multiSpelling.SpellCheck(wd))
                                {
                                    st = wd;
                                    break;
                                }
                                else if (multiSpelling.IsSimilarSpellCheck(wd))
                                {
                                    foundSimilarWord = true;
                                    st = wd;
                                }
                                else
                                {
                                    if (!foundSimilarWord)
                                    {
                                        st = wd;
                                    }
                                }
                         
                            }
                        }
                    }
                }
            }
            return st.Trim();
        }
        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Vietnam Maritime University
Vietnam Vietnam
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions