Главная    Почта    Новости    Каталог    Одноклассники    Погода    Работа    Игры     Рефераты     Карты
  
по Казнету new!
по каталогу
в рефератах

Программа распознавания символов



 Другие рефераты
Программа на Delphi Программа по информатике и вычислительной технике Программа сложной структуры с использованием меню Программа эмуляции развития популяций животных

Белорусский Государственный Университет Информатики и Радиоэлектроники.



                             Контрольная работа
                                по дисциплине
                                   «МАГИ»

                     «Программа распознавания символов»



                                          Выполнил студент группы 500501
                                          Балахонов Е.В.

                                  Задание.


      Требуется  написать  программу,  способную   распознавать   графически
представленные символы в виде растрового  изображения  и  преобразовывать  в
обычный текст.
      - платформа: Win32,
      - формат графического изображения: Windows Bitmap (BMP), 8 бит,
      - шрифт для распознавания: Arial, 16



                          Выбор средств разработки.


      В качестве среды разработки будет использоваться Borland  C++  Builder
5.


                           Распознавание символов.



Этап 1. Выделение контура объекта, определение его границ.


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

Общее описание алгоритма.



     Отслеживающие  алгоритмы  основаны  на   том,   что   на   изображении
отыскивается объект (первая встретившаяся точка объекта)  и  контур  объекта
отслеживается и векторизуется. Достоинством данных  алгоритмов  является  их
простота, к недостаткам  можно  отнести  их  последовательную  реализацию  и
некоторую сложность при  поиске  и  обработке  внутренних  контуров.  Пример
отслеживающего алгоритма - "алгоритма жука" - приведен  на  рис.  5.12.  Жук
начинает движение с белой области по направлению к  черной,  Как  только  он
попадает на черный элемент, он поворачивает налево и переходит к  следующему
элементу. Если этот элемент белый, то жук поворачивается  направо,  иначе  -
налево. Процедура повторяется до тех пор, пока жук не  вернется  в  исходную
точку. Координаты точек перехода с черного на белое и с белого на  черное  и
описывают границу объекта.

     На рис. 1 показана схема работы такого алгоритма.
[pic]
            Рис. 1. Схема работы отслеживающего алгоритма «жука».



Этап 2. Построение на основе контура объекта скелетной линии.


      При нахождении новой точки контура,  рассчитывается  расстояние  между
предыдущей найденной точкой и новой. Если оно  превышает  некоторую  границу
(по умолчанию в 5 единиц),  она запоминается. К концу  построения  скелетной
линии программа имеет массив  координат  вершин  ломаной,  которая  является
скелетной линией объекта.


Этап 3. Сравнение полученной скелетной линии с списком шаблонов.


      После построения скелетной линии производится сравнение ее с списком
шаблонов известных символов. При нахождении совпадения, программа
записывает в строку найденный символ.



                          Исходный текст программы.


//--------------------------------------------------------------------------
-

#include 
#pragma hdrstop

#include 
#include 

#include "ChildFormUnit.h"
#include "MainFormUnit.h"
#include "AverageFilterDialogFormUnit.h"
#include "OSRFormUnit.h"

//--------------------------------------------------------------------------
-
#pragma package(smart_init)
#pragma resource "*.dfm"
TChildForm *ChildForm;
TTemplates Templates;
//--------------------------------------------------------------------------
-
__fastcall TChildForm::TChildForm(TComponent* Owner)
        : TForm(Owner)
{
}
//--------------------------------------------------------------------------
-
bool __fastcall TChildForm::LoadImage(AnsiString FileName)
{
 try
 {
  Image1->Picture->LoadFromFile(FileName);
 }
 catch (EInvalidGraphic& Exception)
 {
  AnsiString Error = "Ошибка загрузки файла изображения! Ошибка системы: ";
  Error += Exception.Message;
  MessageBox(this->Handle, Error.c_str(), "Ошибка", MB_OK | MB_ICONERROR);
  return false;
 }

 if (Image1->Picture->Bitmap->PixelFormat != pf8bit)
 {
  MessageBox(Handle,"Такой формат файла пока не подерживается...",
                    "Слабоват я пока...",MB_OK | MB_ICONSTOP |
MB_APPLMODAL);
  return false;
 }

 return true;
}
//--------------------------------------------------------------------------
-
void __fastcall TChildForm::FormClose(TObject *Sender,
      TCloseAction &Action)
{
 MainForm->DeleteActiveChildForm();
}
//--------------------------------------------------------------------------
-
void __fastcall TChildForm::AverageFilter()
{
 AverageFilterDialogForm = new TAverageFilterDialogForm(this);
 if (AverageFilterDialogForm->ShowModal() == mrCancel)
 {
  delete AverageFilterDialogForm;
  return;
 }

 int Value = atoi(AverageFilterDialogForm->Edit1->Text.c_str());

 delete AverageFilterDialogForm;

 Byte* PrevisionLine = NULL;
 Byte* CurrentLine = NULL;
 Byte* NextLine = NULL;
 int I = 0, J = 0;
 int Summ = 0;

 for (I = 0; I <= Image1->Picture->Bitmap->Height - 1; I++)
 {
  CurrentLine = (Byte*)Image1->Picture->Bitmap->ScanLine[I];
  for (J = 0; J <= Image1->Picture->Bitmap->Width - 1; J++)
  {
   Summ = 0;

   if (I > 0)
   {
    PrevisionLine = (Byte*)Image1->Picture->Bitmap->ScanLine[I - 1];
    if (J > 0)
    {
     Summ += PrevisionLine[J - 1];
    }

    Summ = Summ + PrevisionLine[J];

    if (J + 1 < Image1->Picture->Bitmap->Width)
    {
     Summ += PrevisionLine[J + 1];
    }
   }

   if (J > 0)
   {
    Summ += CurrentLine[J - 1];
   }

   Summ += CurrentLine[J];

   if (J + 1 < Image1->Picture->Bitmap->Width)
   {
    Summ += CurrentLine[J + 1];
   }

   if (I + 1 < Image1->Picture->Bitmap->Height)
   {
    NextLine = (Byte*)Image1->Picture->Bitmap->ScanLine[I + 1];
    if (J > 0)
    {
     Summ += NextLine[J - 1];
    }

    Summ += NextLine[J];

    if (J + 1 < Image1->Picture->Bitmap->Width)
    {
     Summ += NextLine[J + 1];
    }
   }

   if ((int)(Summ / 9) <= Value)
    CurrentLine[J] = (Byte) Summ / 9;
  }
 }
 Image1->Visible = false;
 Image1->Visible = true;
}
//--------------------------------------------------------------------------
-
// Расстояние между двумя точками
int Distance(TVertex& V1, TVertex& V2)
{
 int a = abs(V1.Y - V2.Y);
 int b = abs(V1.X - V2.X);
 return sqrt(a*a + b*b);
}

//--------------------------------------------------------------------------
-
void __fastcall TChildForm::OSR()
{
 // Пороговое расстояние для простроения упрощенной фигуры
 const int Treshold = 5;

 // Сюда сохраняется результат распознования
 AnsiString Result;

 // Отладочная форма с изображением для работы
 OSRForm = new TOSRForm(this);

 // Направления движения жука
 typedef enum {North, East, South, West} TDirectional;
 TDirectional Direct;

 // Координаты первой встречи с текущим объектом
 int X,Y;

 // Временно их используем для задания нового размера рабочего изображения
 X = OSRForm->Width - OSRForm->Image1->Width;
 Y = OSRForm->Height - OSRForm->Image1->Height;
 OSRForm->Image1->Picture->Bitmap->Assign(Image1->Picture->Bitmap);
 OSRForm->Width = OSRForm->Image1->Width + X;
 OSRForm->Height = OSRForm->Image1->Height + Y;
 OSRForm->Image1->Canvas->Rectangle(0, 0, OSRForm->Image1->Width - 1,
                                    OSRForm->Image1->Height - 1);

 Graphics::TBitmap* FromImage = Image1->Picture->Bitmap;
 Graphics::TBitmap* ToImage = OSRForm->Image1->Picture->Bitmap;

 // Текущие координаты маркера
 int cX,cY;

 // Максимальные координаты, которые занимает фигура
 int MaxX = 0;
 int MaxY = FromImage->Height;

 // От этой координаты начинается новое сканирование по Y
 int BeginY = 0;

 // Обрабатываемые линии
 Byte *Line, *ToLine;

 char Symb = 'А';

 // Текущий байт
 Byte B = 0;

 bool SkipMode = false;
 while (true)
 {
  // Список координат текущего объекта
  TShapeVector ShapeVector;
  // Временная структура координат точки
  TVertex Vertex;

  // Поиск любого объекта
  // Идем до тех пор, пока не встретим черную область
  for (X = MaxX; X < FromImage->Width; X++)
  {
   for (Y = BeginY; Y < MaxY; Y++)
   {
    Line = (Byte*)FromImage->ScanLine[Y];
    if (Line[X] < 255)
     goto FindedLabel;
   }

   if ((X + 1 == FromImage->Width) && (Y == FromImage->Height))
   {
    X++;
    goto FindedLabel;
   }

   // Если прошли до самого правого края, расширяем границы поиска до низа
   if (X + 1 == FromImage->Width)
   {
    X = 0;

    MaxX = 0;
    BeginY = MaxY;
    MaxY = FromImage->Height;
   }

  }
FindedLabel:

  // Если не нашли ни одного черного пиксела, то выходим из процедуры
  if ((X == FromImage->Width) && (Y == FromImage->Height))
   break;

  // Сначала задача найти максимальные границы обнаруженной фигуры,
  // чтобы потом от нее начинать строить скелет
  // Также ищем самую верхнюю точку фигуры, для начала построения
  int MinX = Image1->Picture->Width;  // Самая левая координата

  MaxX = 0;
  MaxY = 0;

  // Самая верхняя точка
  TVertex TopPoint;
  TopPoint.Y = Image1->Picture->Height;

  // Поворачиваем налево (новое направление - север)
  cX = X;
  cY = Y - 1;

  Direct = North;
  Line = (Byte*)FromImage->ScanLine[cY];

  // Пока не придем в исходную точку, выделяем контур объекта
  while ((cX != X) || (cY != Y))
  {
   // В зависимости от текущего направления движения жука
   switch (Direct)
   {
     // Север
    case North:
    {
     B = Line[cX];
 
12
скачать работу


 Другие рефераты
Законодательство России в период 1237-1497 гг.
Феномен бюрократии: социальная и политическая сущность
Социальное партнерство
Особенности российского модернизма


 

Отправка СМС бесплатно

На правах рекламы


ZERO.kz
 
Модератор сайта RESURS.KZ