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
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 Form1()
{
InitializeComponent();
label3.Text = "";
for (int i = 0; i < charcount; i++) {
label3.Text += Convert.ToChar(firstchar+i) + " ";
}
setcomponent();
}
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;
}
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];
}
this.Run();
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));
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);
Color clr = (Color)bmp.GetPixel(i, j);
digitizearray[y * x + y] += Math.Sqrt(clr.R * clr.R + clr.B * clr.B + clr.G * clr.G);
}
}
return Scale(digitizearray);
}
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));
Bitmap img = new Bitmap(size.Width, size.Height);
Graphics bmp = Graphics.FromImage(img);
bmp.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
bmp.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
bmp.Clear(Color.White);
bmp.DrawString(Chr.ToString(), fnt, new SolidBrush(Color.Black), new Point(0,0), new StringFormat());
addnoisepercent(size, bmp, addnoise);
pictureBox1.Image = img;
Application.DoEvents();
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);
Color clr = img.GetPixel(i, j);
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;
}
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();
}
}
}