на тему рефераты Информационно-образоательный портал
Рефераты, курсовые, дипломы, научные работы,
на тему рефераты
на тему рефераты
МЕНЮ|
на тему рефераты
поиск
Распознавание графических символов
Если проводилось сохранение обучения, то можно не обучать. Для распознавания в таком случае надо делать следующие: открываешь распознаваемое изображение, нажимаешь "Сегментация", нажимаешь "загрузить", нажимаешь "распознать".

- В записке в графической части нужно вставить некоторые свои данные, я их отметил красным.

- путь к EXE-шнику: \WordSearcher\WordSearcher\bin\Debug\ WordSearcher.exe

Если будут какие-то баги или вопросы, сообщай - исправлю.

С уважением, Свирко Юрий

Mail: sv1r4.sd@gmail.com

Phone: 8-033-63-123-60

ЛИСТИНГ ПРОГРАММЫ

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

namespace WordSearcher

{

public partial class FormMain : Form

{

/// <summary>

/// Флаг разрешения распознавания

/// </summary>

bool enableRecognize = false;

/// <summary>

/// Размер битмапа со словом "Указ"

/// к этому размеру подгоняются все отсалдьные распознаваемые битмапы

/// </summary>

private static Size imSize = new Size(65, 25);

/// <summary>

/// Состояние формы

/// </summary>

private FormState formState = FormState.Empty;

/// <summary>

/// Масив битмапов сос словами текста

/// </summary>

private List<Bitmap> words;

/// <summary>

/// Объект класса для распознавания(персептрон)

/// </summary>

private Recognizer r = new Recognizer(imSize, 750, 2);

/// <summary>

/// Метод для делания активными неактивными кнопок управления

/// в зависимости от этапа обработк изображения

/// </summary>

/// <param name="fs">текущее состояние</param>

private void ButtonsEnabled(FormState fs)

{

formState = fs;

switch (fs)

{

case FormState.Empty:

buttonOpen.Enabled = true;

buttonSegment.Enabled = false;

buttonRecognize.Enabled = false;

buttonTeach.Enabled = false;

buttonLoadTeaching.Enabled = false;

buttonSaveTeaching.Enabled = false;

pictureBoxMain.Image = null;

dataGridViewSegments.Rows.Clear();

break;

case FormState.Open:

buttonOpen.Enabled = true;

buttonSegment.Enabled = true;

buttonRecognize.Enabled = false;

buttonTeach.Enabled = false;

buttonLoadTeaching.Enabled = false;

buttonSaveTeaching.Enabled = false;

dataGridViewSegments.Rows.Clear();

break;

case FormState.Segmented:

buttonOpen.Enabled = true;

buttonSegment.Enabled = true;

if (enableRecognize)

buttonRecognize.Enabled = true;

else

buttonRecognize.Enabled = false;

buttonTeach.Enabled = true;

buttonLoadTeaching.Enabled = true;

buttonSaveTeaching.Enabled = false;

break;

case FormState.Teached:

buttonOpen.Enabled = true;

buttonSegment.Enabled = false;

buttonRecognize.Enabled = true;

buttonTeach.Enabled = false;

buttonLoadTeaching.Enabled = false;

buttonSaveTeaching.Enabled = true;

enableRecognize = true;

break;

case FormState.Deserialized:

buttonOpen.Enabled = true;

buttonSegment.Enabled = false;

buttonRecognize.Enabled = true;

buttonTeach.Enabled = false;

buttonLoadTeaching.Enabled = false;

buttonSaveTeaching.Enabled = true;

enableRecognize = true;

break;

case FormState.Recognized:

buttonOpen.Enabled = true;

buttonSegment.Enabled = false;

buttonRecognize.Enabled = true;

buttonTeach.Enabled = false;

buttonLoadTeaching.Enabled = true;

buttonSaveTeaching.Enabled = true;

break;

}

}

public FormMain()

{

InitializeComponent();

}

private void buttonOpen_Click(object sender, EventArgs e)

{

try

{

Bitmap b;

if (openFileDialog1.ShowDialog() == DialogResult.OK)

else

{

this.ButtonsEnabled(FormState.Empty);

}

}

catch (Exception ex)

{

MessageBox.Show(ex.Message);

}

}

private void buttonSegment_Click(object sender, EventArgs e)

{

//Получаем набор битмапов соответствующих словам текста

words = Segmentation.GetWords((Bitmap)pictureBoxMain.Image);

dataGridViewSegments.RowCount = words.Count;

int i =0;

//Перебираем слов и отображаем в таблице

foreach (Bitmap word in words)

{

dataGridViewSegments.Rows[i].Cells[0].Value = word;

i++;

}

ButtonsEnabled(FormState.Segmented);

}

private void buttonRecognize_Click(object sender, EventArgs e)

{

int i = 0;

foreach (Bitmap word in words)

{

dataGridViewSegments.Rows[i].Cells[1].Value = r.Recognize(Recognizer.NormalizeBitmap(word,imSize));

i++;

}

ButtonsEnabled(FormState.Recognized);

}

private void buttonTeach_Click(object sender, EventArgs e)

{

//Перебираем слова и обучаем ими

//т.к. класса для распознаваня два то

//первый класс обучаем просто изображение слова

//а второй обучаем противопорложным изображение(т.е инвертируем цвета исходного изображения)

for (int i = 0; i < 5; i++)

{

foreach (Bitmap word in words)

{

r.Teach(Recognizer.NormalizeBitmap(word, imSize), 0);

r.Teach(Recognizer.InverseBitmap(Recognizer.NormalizeBitmap(word, imSize)), 1);

}

}

ButtonsEnabled(FormState.Teached);

}

private void buttonSaveTeaching_Click(object sender, EventArgs e)

{

r.SerializeParams();

ButtonsEnabled(FormState.Serialized);

}

private void buttonLoadTeaching_Click(object sender, EventArgs e)

{

r.DeserializeParams();

ButtonsEnabled(FormState.Deserialized);

}

private void FormMain_Load(object sender, EventArgs e)

{

this.ButtonsEnabled(FormState.Empty);

}

}

// <summary>

/// Состояния изображения

/// </summary>

enum FormState

{

/// <summary>

/// изображение не открыто

/// </summary>

Empty,

/// <summary>

/// Изображение открыто

/// </summary>

Open,

/// <summary>

/// Сегментировано

/// </summary>

Segmented,

/// <summary>

/// Персептрон обучен

/// </summary>

Teached,

/// <summary>

/// Параметры персептрона сохранены

/// </summary>

Serialized,

/// <summary>

/// Параметры персептрона загружены

/// </summary>

Deserialized,

/// <summary>

/// Распознано

/// </summary>

Recognized

}

}

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Drawing;

using System.Windows.Forms;

using System.IO;

using System.Runtime.Serialization.Formatters.Binary;

namespace WordSearcher

{

/// <summary>

/// Реализует распозноание изображений

/// на базе персептрона

/// </summary>

class Recognizer

{

/// <summary>

/// матрица знаков входов персептрона

/// </summary>

private int[,] xa;

/// <summary>

/// Массив лямд

/// </summary>

private int[,] l;

/// <summary>

/// Массив имен классов

/// </summary>

private string[] classes = {"Указ",

"Не указ"};

/// <summary>

/// Массив имен классов

/// </summary>

public string[] ClassesList

{

get { return classes; }

}

/// <summary>

/// Инициализирует xa-матрицу

/// </summary>

/// <param name="sz">размер изображения</param>

/// <param name="aCount">количесвто а-элементов</param>

/// <param name="lCount">количесвто классов</param>

public Recognizer(Size sz, int aCount, int lCount)

{

Random r = new Random();

//Создание матрцы ха

xa = new int[sz.Height * sz.Width, aCount];

//Создание матрицы лямд

l = new int[lCount,aCount];

//Первоначальная

//иницализация лямд еденицами

for (int i = 0; i < l.GetLength(0); i++)

{

for (int j = 0; j < l.GetLength(1); j++)

{

l[i, j] = 1;

}

}

//заполнение матрицы

//для каждого рецептора(строчки)

//назначаетя только один а-элемент(столбец) со знаком + или -

for (int i = 0; i < xa.GetLength(0); i++)

{

xa[i, r.Next(aCount)] = (int)Math.Pow(-1, r.Next(1, 3));

}

}

/// <summary>

/// Обучение персептрона

/// </summary>

/// <param name="b">битмап для обучения</param>

/// <param name="classindex">имя класса к ккоторому относиться изображение</param>

public void Teach(Bitmap b, int classindex)

{

int[] x = new int[b.Height * b.Width];

int k = 0;

//Инициализация входных рецепторов

for (int i = 0; i < b.Width; i++)

{

for (int j = 0; j < b.Height; j++)

{

if (b.GetPixel(i, j) == Color.FromArgb(0, 0, 0))

x[k] = 1;

k++;

}

}

//Вектор сумм рецепторов

int[] sumx = new int[xa.GetLength(1)];

//Вектор выходов А-элементов

int[] outa = new int[xa.GetLength(1)];

//суммирование сигналов от рецепторов

for (int i = 0; i < xa.GetLength(1); i++)

{

for (int j = 0; j < xa.GetLength(0); j++)

{

sumx[i] += x[j] * xa[j, i];

}

//Если сумма больше нуля выход а элемента 1

if (sumx[i] > 0)

outa[i] = 1;

}

//изменение коэфициетов лямда

for (int i = 0; i < outa.Length; i++)

{

//Если а-элемент возбужден то изменяем лямды

if (outa[i] == 1)

{

//перебор всех классов

for (int j = 0; j < l.GetLength(0); j++)

{

//Увеличение на 1 лямд для класса который обучается

//и уменьшение для всех осатльных

if (classindex == j)

l[j, i]++;

else

l[j, i]--;

}

}

}

}

/// <summary>

/// Распознавание изобржения

/// </summary>

/// <param name="b">битмап изображения</param>

/// <returns>имя класса к которому отнесено изображение</returns>

public string Recognize(Bitmap b)

{

int[] x = new int[b.Height * b.Width];

int k = 0;

//Инициализация входных рецепторов

for (int i = 0; i < b.Width; i++)

{

for (int j = 0; j < b.Height; j++)

{

if (b.GetPixel(i, j) == Color.FromArgb(0, 0, 0))

x[k] = 1;

k++;

}

}

//Вектор суммрецепторов

int[] sumx = new int[xa.GetLength(1)];

//Вектор выходов А-элементов

int[] outa = new int[xa.GetLength(1)];

//суммирование сигналов от рецепторов

for (int i = 0; i < xa.GetLength(1); i++)

{

for (int j = 0; j < xa.GetLength(0); j++)

{

sumx[i] += x[j] * xa[j, i];

}

//Если сумма больше нуля выход а элемента 1

if (sumx[i] > 0)

outa[i] = 1;

}

//Создание масива значений сумматоров

//каждый для отдельного класса

int[] sum = new int[l.GetLength(0)];

//Нахождение значений сумматоров для каждого класса

for (int i = 0; i < sum.Length; i++)

{

for (int j = 0; j < xa.GetLength(1); j++)

{

sum[i] += outa[j] * l[i, j];

}

}

//нахождение максимального значения сумматор

//именно оно соответствует распознанному классу

int max = sum[0];

int maxindex = 0;

for (int i = 1; i < sum.Length; i++)

{

if (max < sum[i])

{

max = sum[i];

maxindex = i;

}

}

//Возвращается имя класса с максимальным значением сумматора

return classes[maxindex];

}

/// <summary>

/// Сериализация массива лямд(сохранение в файл) для сохранения обученяи персептрона

/// </summary>

public void SerializeParams()

{

try

{

BinaryFormatter bf = new BinaryFormatter();

FileStream fs = new FileStream("l.dat", FileMode.Create);

bf.Serialize(fs, l);

fs.Close();

bf = new BinaryFormatter();

fs = new FileStream("xa.dat", FileMode.Create);

bf.Serialize(fs, xa);

fs.Close();

}

catch (Exception ex)

{

MessageBox.Show(ex.Message);

}

}

/// <summary>

/// Десериализация массива лямд(чтение из файла)

/// </summary>

public void DeserializeParams()

{

try

{

BinaryFormatter bf = new BinaryFormatter();

FileStream fs = new FileStream("l.dat", FileMode.Open);

l = (int[,])bf.Deserialize(fs);

fs.Close();

bf = new BinaryFormatter();

fs = new FileStream("xa.dat", FileMode.Open);

xa = (int[,])bf.Deserialize(fs);

fs.Close();

}

catch (Exception ex)

{

MessageBox.Show(ex.Message);

}

}

/// <summary>

/// Подгонка битмапа по размеру и его бинаризация

/// </summary>

/// <param name="b">входной битмап</param>

/// <param name="sz">новый размер битмапа</param>

/// <returns>нормализованный битмап</returns>

public static Bitmap NormalizeBitmap(Bitmap b, Size sz)

{

//Подгонка размера

Bitmap inImg = new Bitmap(b, sz);

//Создание выходного битмапа на основе подогнанного

Bitmap outImg = new Bitmap(inImg);

//находим среднее значение яркости

int sum = 0;

for (int i = 0; i < outImg.Width; i++)

{

for (int j = 0; j < outImg.Height; j++)

{

Color cl = ((Bitmap)inImg).GetPixel(i,j);

sum += (cl.R + cl.G + cl.B) / 3;

}

}

int sredn = sum / (inImg.Width * inImg.Height);

//Просматриваем изображнеи и бинаризуем его

for (int i = 0; i < outImg.Width; i++)

{

for (int j = 0; j < outImg.Height; j++)

{

Color cl = ((Bitmap)inImg).GetPixel(i,j);

int gray = (cl.R + cl.G + cl.B) / 3;

if (gray > sredn)

outImg.SetPixel(i, j, Color.FromArgb(255, 255, 255));

else

outImg.SetPixel(i, j, Color.FromArgb(0, 0, 0));

}

}

return outImg;

}

/// <summary>

/// Инверсия цвета битмапа

/// </summary>

/// <param name="b"></param>

/// <returns></returns>

public static Bitmap InverseBitmap(Bitmap b)

{

Bitmap outImg = new Bitmap(b.Width, b.Height);

for (int i = 0; i < b.Width; i++)

{

for (int j = 0; j < b.Height; j++)

{

Color c = b.GetPixel(i,j);

outImg.SetPixel(i, j, Color.FromArgb(255 - c.R, 255 - c.G, 255 - c.B));

}

}

return outImg;

}

}

}

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Drawing;

namespace WordSearcher

{

class Segmentation

{

/// <summary>

/// Разбиение битмапа с текстоми на строки

/// </summary>

/// <param name="b">исходный битмап</param>

/// <returns>коллекция строк</returns>

public static List<Bitmap> GetStrings(Bitmap text)

{

List<Bitmap> strs = new List<Bitmap>();

List<int> whiteLineIndexes = new List<int>();

//Находим все белые горзонатльные линии на ихображении

//и запоминаем их индексы

for (int j = 0; j < text.Height; j++)

{

bool whiteLineFound = true;

for (int i = 0; i < text.Width; i++)

{

if (text.GetPixel(i, j) != Color.FromArgb(255, 255, 255))

{

whiteLineFound = false;

break;

}

}

if (whiteLineFound)

whiteLineIndexes.Add(j);

}

//Выделение строк между белыми несоседними линиями

for (int i = 0; i < whiteLineIndexes.Count-1; i++)

{

if (whiteLineIndexes[i + 1] - whiteLineIndexes[i] > 4)

{

strs.Add(text.Clone(

new Rectangle(

0,

whiteLineIndexes[i],

text.Width,

whiteLineIndexes[i + 1] - whiteLineIndexes[i]+1),

System.Drawing.Imaging.PixelFormat.Format24bppRgb));

}

}

return strs;

}

/// <summary>

/// Получить список слов отдельной строки

/// </summary>

/// <param name="str">битмап со строкой текста</param>

/// <returns>спсиок слов строки</returns>

public static List<Bitmap> GetStringWords(Bitmap str)

{

List<Bitmap> words = new List<Bitmap>();

List<int> whiteLineIndexes = new List<int>();

//Находим все белые вертикальные линии на изображении

//и запоминаем их индексы

for (int i = 0; i < str.Width; i++)

{

bool whiteLineFound = true;

for (int j = 0; j < str.Height; j++)

{

if (str.GetPixel(i, j).R < 100)

{

whiteLineFound = false;

break;

}

}

if (whiteLineFound)

whiteLineIndexes.Add(i);

}

//Ширина пробела

int spaceWidth = 0;

int sum = 0;

int n = 0;

//Вычисление ширины пробела

for (int i = 0; i < whiteLineIndexes.Count - 1; i++)

{

int d = whiteLineIndexes[i + 1] - whiteLineIndexes[i];

if (d > 1)

{

sum += d;

n++;

}

}

//Ширина пробела необходимо при дальнейшем выделении слов

//коэф. подобран вручную

spaceWidth = (int)Math.Round(sum * 0.45 / n + 0.1);

//начальная координата слова

int wordBegin = 0;

//конечная координат слова

int wordEnd = 0;

//флаг указывающий на то найденно ли начало слова или нет

//перволдится обратно в фолс после нахождения конца слова

bool wordFound = false;

//Счетчик ширины белой полоски

int whiteWidth = 0;

//Выделение слов

for (int i = 0; i < whiteLineIndexes.Count - 1; i++)

{

//если линии не соседние и флаг wordFound фолс т.е.

//слово еще не найдено

//запоминаем координату певрой линии это будет

//координатой началом слова

if ((whiteLineIndexes[i + 1] - whiteLineIndexes[i] > 1) &&

!wordFound)

{

//обнуление счетчика идущих подряд белыхз линий

whiteWidth = 0;

//флаг найденного слова в тру

wordFound = true;

//инициализируем начальную координату слова

wordBegin = whiteLineIndexes[i];

}

//инициализируем конечную координату слова

//если найдены не сосдение линии

//но не обрезаем битмап и не добавлям его в коллекцию

//т.к. необходисмо зделать проверку на ширину пробела

if ((whiteLineIndexes[i + 1] - whiteLineIndexes[i] > 1) &&

wordFound)

{

whiteWidth = 0;

wordEnd = whiteLineIndexes[i + 1];

}

//Если найденны соседние белые линии

//инкремируем счетчик белых линий и сравниваем ширину идущих подрд белых линий

//с ранее высчитаной средней шириной пробела

if (whiteLineIndexes[i + 1] - whiteLineIndexes[i] == 1)

{

whiteWidth++;

if ((whiteWidth >= spaceWidth) &&

(wordEnd - wordBegin > 1))

{

//Обрезаем и добавляем слово в коллекцию

words.Add(TrimBitmap(

str.Clone(

new Rectangle(

wordBegin,

0,

wordEnd - wordBegin + 1,

str.Height),

System.Drawing.Imaging.PixelFormat.Format24bppRgb)

)

);

//обнуляем счетчики

//и флаги

whiteWidth = 0;

wordFound = false;

wordBegin = 0;

wordEnd = 0;

}

}

}

return words;

}

/// <summary>

/// Получить битмапы всех слов в тексте

/// </summary>

/// <param name="text">битмап с текстом</param>

/// <returns>коллекция всех слов в тексте</returns>

public static List<Bitmap> GetWords(Bitmap text)

{

List<Bitmap> strs = GetStrings(text);

List<Bitmap> words = new List<Bitmap>();

foreach (Bitmap str in strs)

{

foreach (Bitmap word in GetStringWords(str))

{

words.Add(word);

}

}

return words;

}

/// <summary>

/// Обрезка белых полей вокруг изображения на битмапе

/// </summary>

/// <param name="bmp"></param>

/// <returns></returns>

public static Bitmap TrimBitmap(Bitmap bmp)

{

int left = 0;

int right = 0;

int top = 0;

int bottom = 0;

bool go = true;

//проход сверху

for (int j = 0; (j < bmp.Height) && go; j++)

{

for (int i = 0; (i < bmp.Width) && go; i++)

{

if (bmp.GetPixel(i, j) != Color.FromArgb(255, 255, 255))

{

go = false;

top = j;

}

}

}

go = true;

//проход снизу

for (int j = bmp.Height - 1; (j >= 0) && go; j--)

{

for (int i = 0; (i < bmp.Width) && go; i++)

{

if (bmp.GetPixel(i, j) != Color.FromArgb(255, 255, 255))

{

go = false;

bottom = j;

}

}

}

go = true;

//проход слева

for (int i = 0; (i < bmp.Width) && go; i++)

{

for (int j = 0; (j < bmp.Height) && go; j++)

{

if (bmp.GetPixel(i, j) != Color.FromArgb(255, 255, 255))

{

go = false;

left = i;

}

}

}

go = true;

//проход спарва

for (int i = bmp.Width - 1; (i >= 0) && go; i--)

{

for (int j = 0; (j < bmp.Height) && go; j++)

{

if (bmp.GetPixel(i, j) != Color.FromArgb(255, 255, 255))

{

go = false;

right = i;

}

}

}

return bmp.Clone(new Rectangle(left, top, right - left + 1, bottom - top + 1), System.Drawing.Imaging.PixelFormat.Format24bppRgb);

}

}

}

ОПИСЬ ЛИСТОВ ГРАФИЧЕСКОЙ ЧАСТИ

Лист 1 - Схема приложения

Функциональная схема приложения

Лист 2 - Диаграмма классов

Лист 3 - Результаты работы программы.

Лист 4 - Схема алгоритма сегментации текста.

Страницы: 1, 2



© 2003-2013
Рефераты бесплатно, курсовые, рефераты биология, большая бибилиотека рефератов, дипломы, научные работы, рефераты право, рефераты, рефераты скачать, рефераты литература, курсовые работы, реферат, доклады, рефераты медицина, рефераты на тему, сочинения, реферат бесплатно, рефераты авиация, рефераты психология, рефераты математика, рефераты кулинария, рефераты логистика, рефераты анатомия, рефераты маркетинг, рефераты релиния, рефераты социология, рефераты менеджемент.