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
}
}