Click here to Skip to main content
15,884,298 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.9K   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 System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Collections;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows;
using System.Windows.Forms;

namespace UPImage.Data
{
    public struct ImageData
    {
        public String Label { get; set; }
        public Bitmap Image { get; set; }

        public ImageData(String label, Bitmap image)
            : this()
        {
            Label = label;
            Image = image;
        }
    }
    public struct ByteImageData
    {
        public Char Label { get; set; }
        public byte[] Image { get; set; }

        public ByteImageData(Char label, byte[] image)
            : this()
        {
            Label = label;
            Image = image;
        }
    }
    public class UPDataProvider : IDisposable
    {
        //private parameters
        private int _maxDegreeOfParallelism = Environment.ProcessorCount;
        private List<ImageData> imagePatterns;
        private List<ByteImageData> byteImagePatterns;
        private UPFolder folder;
        private Size patternSize;
        public bool DatabaseLoaded { get; private set; }
        public int PatternsCount { get; private set; }
        public int[] RandomTrainingPattern { get; private set; }
        public int MaxDegreeOfParallelism
        {
            get
            {
                return _maxDegreeOfParallelism;
            }

            set
            {
                if (value == _maxDegreeOfParallelism)
                    return;

                if ((value == 0) || (value > Environment.ProcessorCount))
                    _maxDegreeOfParallelism = -1;
                else
                    _maxDegreeOfParallelism = value;

                ParallelOption.MaxDegreeOfParallelism = _maxDegreeOfParallelism;
            }
        }
        public ParallelOptions ParallelOption { get; private set; }
        public UPFolder Folder
        {
            get
            {
                return folder;
            }
        }
        public List<ImageData> ImagePatterns
        {
            get
            {
                return imagePatterns;
            }
        }
        public List<ByteImageData> ByteImagePatterns
        {
            get
            {
                return byteImagePatterns;
            }
           
        }
        public Size PatternSize
        {
            get
            {
                return patternSize;
            }
            set
            {
                if (patternSize == value)
                    return;
                patternSize = value;
            }
        }
        bool isDataStop;
        public bool IsDataStop
        {
            get
            {
                return isDataStop;
            }
            set
            {
                if (isDataStop == value)
                {
                    return;
                }
                else
                {
                    isDataStop = value;
                    lock (this)
                    {
                        folder.IsDataStop = isDataStop;
                    }
                }
            } 
        }
        public UPDataProvider()
        {
            ParallelOption = new ParallelOptions();
            ParallelOption.TaskScheduler = null;
            _maxDegreeOfParallelism = Environment.ProcessorCount;
            ParallelOption.MaxDegreeOfParallelism = _maxDegreeOfParallelism;
            folder = new UPFolder();
            imagePatterns = null;
            byteImagePatterns = null;
            this.IsDataStop = true;
            patternSize = Size.Empty;
        }

        ~UPDataProvider()
        {
            // In case the client forgets to call
            // Dispose , destructor will be invoked for
            Dispose(false);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                // dispose managed resources
                if (folder != null)
                {
                    folder.Dispose();
                    folder = null;
                }
                if (imagePatterns != null)
                {
                    imagePatterns.Clear();
                    imagePatterns = null;
                }
                if (byteImagePatterns != null)
                {
                    byteImagePatterns.Clear();
                    byteImagePatterns = null;
                }
            }

            // free native resources
        }

        public void Dispose()
        {

            Dispose(true);
            GC.SuppressFinalize(this);
        }
        public void LoadUnipenFolderTree(String path)
        {
            folder.FillFolderTree(path);
        }
        /// <summary>
        /// this function will get partern list of a hierachy
        /// </summary>
        /// <param name="folderPath"></param>
        /// <param name="bmplist"></param>
        /// <param name="hierachy"></param>
        public void GetPatternsFromFiles(String folderPath)
        {
            String hierachy = "CHARACTER";
            if (imagePatterns != null)
            {
                imagePatterns.Clear();
                imagePatterns = null;
            }
            imagePatterns = new List<ImageData>();
            patternSize.Width = 29;
            patternSize.Height = 29;
            folder.GetImageData(folderPath, hierachy, imagePatterns, patternSize, 2, true, true);
            byteImagePatterns = GetBytePatterns();
            PatternsCount = imagePatterns.Count;
            
        }
        public void GetPatternsFromFiles(String folderPath,String hierachyString,Size imageSize,int penWidth,bool isGrayscale,bool isLetterOrDigit)
        {
            String hierachy = hierachyString;
            if (imagePatterns != null)
            {
                imagePatterns.Clear();
                imagePatterns = null;
            }
            imagePatterns = new List<ImageData>();
            patternSize.Width = imageSize.Width;
            patternSize.Height = imageSize.Height;
            folder.GetImageData(folderPath, hierachy, imagePatterns, patternSize, penWidth, isGrayscale, isLetterOrDigit);
            byteImagePatterns = GetBytePatterns();
            PatternsCount = imagePatterns.Count;

        }
        private List<ByteImageData> GetBytePatterns()
        {
            List<ByteImageData> bytesList = null;
            this.IsDataStop = false;
            if (imagePatterns.Count > 0)
            {
                bytesList = new List<ByteImageData>();
                Parallel.ForEach(imagePatterns, (pattern,loopstate) =>
                {
                    if (pattern.Image != null)
                    {
                        ByteImageData imgdata = new ByteImageData();
                        String label = pattern.Label;
                        imgdata.Label = label.ToCharArray(1, 1)[0];
                        imgdata.Image = ConvertGrayscaleBitmaptoBytes(pattern.Image);
                        lock (this)
                        {
                            bytesList.Add(imgdata);
                        }
                    }
                    if (isDataStop)
                    {
                        loopstate.Stop();
                    }
                });
                this.IsDataStop = true;
            }
            return bytesList;
        }
    
        private byte[] ConvertGrayscaleBitmaptoBytes(Bitmap original)
        {
            if (original.PixelFormat == PixelFormat.Format8bppIndexed)
            {
                Bitmap gsBitmap =(Bitmap) original.Clone();
                byte[] grayscalebytes = new byte[gsBitmap.Width * gsBitmap.Height];
                BitmapData bmpData = gsBitmap.LockBits(new Rectangle(0, 0, gsBitmap.Width, gsBitmap.Height),
                ImageLockMode.ReadOnly,
                gsBitmap.PixelFormat);
                int bytes = Math.Abs(bmpData.Stride) * gsBitmap.Height;
                byte[] rgbValues = new byte[bytes];

                System.Runtime.InteropServices.Marshal.Copy(bmpData.Scan0, rgbValues, 0, bytes);
                gsBitmap.UnlockBits(bmpData);
                int bmpWidth = gsBitmap.Width;
                int bmpHeight = gsBitmap.Height;
                //
                /*TODO: Check potentially-changing upper bound expression "gsBitmap.Height" which is now called only *once*,
                to ensure the new Parallel.For call matches behavior in the original for-loop
               (where this upper bound expression had previously been evaluated at the start of *every* loop iteration).*/
                Parallel.For(0, bmpHeight, ParallelOption, (h, loopstate) =>
                {
                    for (int w = 0; w < bmpWidth; w++)
                    {
                        grayscalebytes[h * bmpWidth + w] = rgbValues[h * bmpData.Stride + w];
                    }
                    if (isDataStop)
                    {
                        loopstate.Stop();
                    }
                });
                gsBitmap.Dispose();
                return grayscalebytes;
            }
            else
            {
                return null;
            }
        }
    }
}

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