Click here to Skip to main content
15,302,455 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi!

I am implementing an OCR in C#.I downloaded the source code related to identifying a character input from keyboard using neural networks from Code Projects.But when i tried it with a text image it does not identify the character correctly.Please help me in this regards.My source code is given below

C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using xpidea.neuro.net.patterns;
using xpidea.neuro.net.backprop;
using xpidea.neuro.net;
using AForge.Imaging;



namespace OCR
{
    public partial class Form1 : Form
    {
        static public bool ISTerminated;
        public static int Matrixdim = 10;
        public static byte firstchar = (byte)'"';
        public static byte lastchar = (byte)'z';
        public static int charcount = lastchar - firstchar + 1;
        public PatternsCollection trainingPatterns;
        public OCRNetwork backpropNetwork;
        public OpenFileDialog fileopen,fopen;
        public SaveFileDialog savefile;
        public MODI.Document mdf;
        //public System.Windows.Forms.KeyPressEventHandler tabkey;

        public Form1()
        {
            InitializeComponent();
            label3.Text = "";

            for (int i = 0; i < charcount; i++) {
                label3.Text += Convert.ToChar(firstchar+i) + " ";
            }
            setcomponent();

            
        }


        //static public bool ISTerminated;
        
        //inherits backpropogation OCR network

        public class OCRNetwork: BackPropagationRPROPNetwork
        {

            private Form1 owner;

            public OCRNetwork(Form1 owner, int[] nodesInEachLayer): base(nodesInEachLayer)
            {
                this.owner = owner;
            }

            public int BestNodeIndex {

                get {
                    int result = -1;
                    double maxnodeval = 0;
                    double minerror = double.PositiveInfinity;
                    for (int i = 0; i < this.OutputNodesCount;i++) {
                        NeuroNode node = OutputNode(i);

                        if ((node.Value > maxnodeval) || ((node.Value >= maxnodeval) && (node.Error < minerror))) {
                            maxnodeval = node.Value;
                            minerror = node.Error;
                            result = i;
                        }
                    }
                    return result;
                }

            }

            private int OutputPatternIndex(Pattern pattern) {
                for (int i = 0; i < pattern.OutputsCount;i++) 
                    if(pattern.Output[i]==1)
                        return i;                    
                
                return -1;      //if not work check this
            }

            public override void Train(PatternsCollection patterns)
            {
                int iterations = 0;
                if (patterns != null) {
                    double error = 0;
                    int good = 0;

                    while (good < patterns.Count) {
                        if (Form1.ISTerminated) return;
                        error = 0;
                        this.owner.progressBar1.Value=good;
                        owner.label1.Text = "Trainning Sequence Is in Progress:" + Convert.ToString(((good * 100) / owner.progressBar1.Maximum)) + "%";
                        good = 0;

                        for (int k = 0; k < patterns.Count;k++) {
                            for (int l = 0; l < NodesInLayer(0);l++) {
                                nodes[l].Value = patterns[k].Input[l];
                                
                            }
                            //ADDNOISE
                            this.Run();

                            //set expected result

                            for (int l = 0; l < this.OutputNodesCount;l++) {
                                error += Math.Abs(this.OutputNode(l).Error);
                                this.OutputNode(l).Error = patterns[k].Output[l];
                            }
                            this.Learn();

                            if (BestNodeIndex == OutputPatternIndex(patterns[k]))
                            {
                                good++;
                            }
                            iterations++;
                            Application.DoEvents();
                        }

                        foreach (NeuroLink link in links) ((EpochBackPropagationLink)link).Epoch(patterns.Count);

                    }
                }

            }

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        public double[] CharToDoubleArray1(System.Drawing.Image img, Font fnt, int arrdim, int addnoise) {

            double[] digitizearray = new double[arrdim * arrdim];

            Graphics grs = label3.CreateGraphics();

            Size size = Size.Round(grs.MeasureString(img.ToString(),fnt)); //get the size of the input character
            //Bitmap img = new Bitmap(size.Width, size.Height);

            Bitmap bs = (Bitmap)img;
            Bitmap bmp = new Bitmap(size.Width,size.Height);
            Graphics gr = Graphics.FromImage((System.Drawing.Image)bmp);
            gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            gr.DrawImage(img, 0, 0, size.Width, size.Height);
            gr.Dispose();
            pictureBox2.Image = bmp;
            

            double xstep = (double)bmp.Width / (double)arrdim;
            double ystep = (double)bmp.Height / (double)arrdim;

            for (int i = 0; i < bmp.Width; i++)
            {
                for (int j = 0; j < bmp.Height; j++)
                {
                    int x = (int)((i / xstep));
                    int y = (int)(j / ystep);

                    //get the color of the pixel
                    Color clr = (Color)bmp.GetPixel(i, j);

                    //we must get the maximum value of the image to scale down the image
                    digitizearray[y * x + y] += Math.Sqrt(clr.R * clr.R + clr.B * clr.B + clr.G * clr.G);
                    //digitizearray[y * x + y] += Math.Sqrt(
                }
            }

            return Scale(digitizearray);



        }

        //this is used to digitize the image

        public double[] CharToDoubleArray(char Chr,Font fnt,int arrdim,int addnoise) {

            double[] digitizearray = new double[arrdim * arrdim];
            Graphics gr = label3.CreateGraphics();
            
            Size size = Size.Round(gr.MeasureString(Chr.ToString(), fnt)); //get the size of the input character
            Bitmap img = new Bitmap(size.Width, size.Height); //generate a bitmap image according to the size of the input
            Graphics bmp = Graphics.FromImage(img);//create a graphic object from the image you created from the input
            bmp.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;//no smoothing is done to curves and lines of the filled area
            bmp.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;//Interpolation of graphic object influences the way an image is shrinked or stretched
            bmp.Clear(Color.White);
            bmp.DrawString(Chr.ToString(), fnt, new SolidBrush(Color.Black), new Point(0,0), new StringFormat());//draw the image from input character

            //check this
            addnoisepercent(size, bmp, addnoise);

            pictureBox1.Image = img;
            Application.DoEvents();

            //we have to scale down the image in order to get values in the range of input values to neural network

            double xstep = (double)img.Width / (double)arrdim;
            double ystep = (double)img.Height / (double)arrdim;

            for (int i = 0; i < img.Width;i++ ) {
                for (int j = 0; j < img.Height;j++) {
                    int x = (int)((i / xstep));
                    int y = (int)(j / ystep);

                    //get the color of the pixel
                    Color clr = img.GetPixel(i, j);

                    //we must get the maximum value of the image to scale down the image

                    digitizearray[y * x + y] += Math.Sqrt(clr.R * clr.R + clr.B * clr.B + clr.G * clr.G);
                }
            }
            return Scale(digitizearray);

        }

        public double[] Scale(double[] src) {
            double maxval = Maxof(src);

            if (maxval != 0) {
                for (int i = 0; i < src.Length; i++) {
                    src[i] = src[i] / maxval;
                }
            }
            return src;
        }

        public double Maxof(double[] src) {
            double res = double.NegativeInfinity;

            foreach (double d in src) {
                if (d > res) {
                    res = d;
                }
                       
            }
            return res; //check this
        }

        public PatternsCollection CreateTrainingPatterns(Font font)
        {
            PatternsCollection result = new PatternsCollection(charcount, Matrixdim * Matrixdim, charcount);
            
            for (int i = 0; i < charcount; i++)
            {
                double[] BitMatrix = CharToDoubleArray(Convert.ToChar(firstchar+i),font,Matrixdim,0);
                for (int j = 0; j < Matrixdim * Matrixdim;j++ ) 
                    result[i].Input[j] = BitMatrix[j];
                                
                result[i].Output[i] = 1;
            }
            return result;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            trainingPatterns = CreateTrainingPatterns(label3.Font);
            tabControl1.SelectedTab = tabPage2;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            backpropNetwork = new OCRNetwork(this, new int[3] { Matrixdim * Matrixdim, (Matrixdim * Matrixdim + charcount) / 2, charcount });
            tabControl1.SelectedTab = tabPage3;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (backpropNetwork == null) {
                MessageBox.Show("Please Create the Network First");
                tabControl1.SelectedTab = tabPage2;
            }

            if (trainingPatterns == null) {
                MessageBox.Show("Please Create the Training Patterns First");
                tabControl1.SelectedTab = tabPage1;
            }

            progressBar1.Maximum = charcount;
            label4.Text = "While the training process is in progress you can go to Character Recognition page and view the recognition quality during training";
            backpropNetwork.Train(trainingPatterns);
            MessageBox.Show("Network training is successfully completed");

        }

        private void button4_Click(object sender, EventArgs e)
        {
            if(backpropNetwork==null){
                MessageBox.Show("Please Create the Network First");
                tabControl1.SelectedTab = tabPage2;
            }
            if (trainingPatterns == null)
            {
                MessageBox.Show("Please Create the Training Patterns First");
                tabControl1.SelectedTab = tabPage1;
            }

            if (savefile.ShowDialog() == DialogResult.OK) {
                backpropNetwork.SaveToFile(savefile.FileName);
            }

        }

        private void button5_Click(object sender, EventArgs e)
        {
            if (backpropNetwork == null) {
                MessageBox.Show("Please Create the Network First");
                tabControl1.SelectedTab = tabPage2;
            }
            if (trainingPatterns == null)
            {
                MessageBox.Show("Please Create the Training Patterns First");
                tabControl1.SelectedTab = tabPage1;
            }
            if(fileopen.ShowDialog()==DialogResult.OK){
                backpropNetwork.LoadFromFile(fileopen.FileName);
                tabControl1.SelectedTab = tabPage4;
            }
        }

        private void setcomponent() {
            this.fileopen = new OpenFileDialog();
            this.savefile = new SaveFileDialog();

            this.fileopen.DefaultExt = "neuro";
            this.fileopen.FileName = "OCRNetwork";
            this.fileopen.Filter = "Neural network (*.neuro)|*.neuro";
            this.fileopen.Title = "Load the Neural Network Pattern";

            this.savefile.DefaultExt = "neuro";
            this.savefile.FileName = "OCRNetwork";
            this.savefile.Filter = "Neural network (*.neuro)|*.neuro";
            this.savefile.Title = "Store the Neural Network Pattern";

            label6.Text = "A";
            label5.Text = "A";
           
        }
        private void tabControl1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e) {
            if(tabControl1.SelectedTab==tabPage4 ){
                if (backpropNetwork == null)
                {
                    MessageBox.Show("Please Create the Network First");
                    tabControl1.SelectedTab = tabPage2;
                }

                label5.Text = e.KeyChar.ToString();
                double[] inputimage = CharToDoubleArray(e.KeyChar, label3.Font, Matrixdim, trackBar1.Value);

                for (int i = 0; i < backpropNetwork.InputNodesCount; i++) 
                    backpropNetwork.InputNode(i).Value = inputimage[i];
                
                backpropNetwork.Run();
                label6.Text = Convert.ToChar(firstchar + backpropNetwork.BestNodeIndex).ToString();
            }
        }

        private void addnoisepercent(Size sz,Graphics gr,int noiseamount) {
            int range = sz.Width * sz.Height * noiseamount / 200;

            for (int i = 0; i < range;i++ ) {
                int x = (int)OCRNetwork.Random(0, sz.Width);
                int y = (int)OCRNetwork.Random(0,sz.Height);

                Rectangle rect = new Rectangle(x, y, 0, 0);
                rect.Inflate(1, 1);
                Brush br;

                if ((OCRNetwork.Random(0, 100)) > 80)
                    br = new SolidBrush(Color.White);
                else
                    br = new SolidBrush(Color.Black);

                gr.FillRectangle(br, rect);
                br.Dispose();
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            string nm;
            fopen = new OpenFileDialog();
            if(fopen.ShowDialog()==DialogResult.OK){
                nm = fopen.FileName;
            }
            pictureBox2.Image = System.Drawing.Image.FromFile(fopen.FileName);
            

        }

        private void button7_Click(object sender, EventArgs e)
        {
            double[] inputimage = CharToDoubleArray1(pictureBox2.Image, label3.Font, Matrixdim, trackBar1.Value);
            for (int i = 0; i < backpropNetwork.InputNodesCount; i++)
                backpropNetwork.InputNode(i).Value = inputimage[i];

            backpropNetwork.Run();
            label6.Text = Convert.ToChar(firstchar + backpropNetwork.BestNodeIndex).ToString();
        }
       

        
    }
}
Posted
Updated 4-Aug-10 22:28pm
v2
Comments
Sandeep Mewara 14-Sep-10 5:28am
   
Too much code!

This is far too much code for anyone to read. If you got this code from an article then use the forum at the end of the article to post a question to the author. Otherwise you need to start testing/debugging to figure out where it is going wrong. When you have narrowed it down to a few lines of code then try editing your question with the details.
   
This is indeed to much code but since it is a neural network you use... did you bother first to train it before using it?

Otherwise, try to narrow it down.

Good luck!
   

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900