Программа розпізнавання символов
TCloseAction &Action) { MainForm→DeleteActiveChildForm (); } //————————————————————————————————————— — void __fastcall TChildForm: AverageFilter () { AverageFilterDialogForm = new TAverageFilterDialogForm (this); if (AverageFilterDialogForm→ShowModal () == mrCancel) { delete AverageFilterDialogForm; return; }. If ((int)(Summ / 9) Visible = false; Image1→Visible = true… Читати ще >
Программа розпізнавання символов (реферат, курсова, диплом, контрольна)
Білоруський Державний Університет Інформатики і Радиоэлектроники.
Контрольна робота з дисциплине.
«МАГИ».
«Програма розпізнавання символов».
Виконав студент групи 500 501.
Балахонів Е.В.
Задание.
Потрібна написати програму, здатну розпізнавати графічно представлені символи як растрового зображення перетворювати на звичайний текст.
— платформа: Win32,.
— формат графічного зображення: Windows Bitmap (BMP), 8 бит,.
— шрифт для розпізнавання: Arial, 16.
Вибір коштів разработки.
Як середовища розробки використовуватиметься Borland З++ 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 Picture->Bitmap->Height — 1; I++) { CurrentLine = (Byte*)Image1->Picture->Bitmap->ScanLine[I]; for (J = 0; J 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) 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];
// Якщо елемент «чорний », повертаємо знову «наліво «if (B < 255).
{.
Direct = West; cX—;
// Може це найбільш ліва координата? if (MinX > cX).
MinX = cX;
}.
// Інакше повертаємо «направо «else.
{.
Direct = East; cX++; if (MaxX < cX).
MaxX = cX;
}.
} break;
// Схід case East:
{.
B = Line[cX];
// Якщо елемент «чорний », повертаємо знову «наліво «if (B < 255).
{.
Direct = North; cY—;
Line = (Byte*)FromImage->ScanLine[cY];
// Може це найбільш верхня точка? if (TopPoint.Y > cY).
{.
TopPoint.Y = cY;
TopPoint.X = cX;
}.
}.
// Інакше повертаємо «направо «else.
{.
Direct = South; cY++;
Line = (Byte*)FromImage->ScanLine[cY]; if (MaxY < cY).
MaxY = cY;
}.
} break;
// Південь case South:
{.
B = Line[cX];
// Якщо елемент «чорний », повертаємо знову «наліво «if (B < 255).
{.
Direct = East; cX++; if (MaxX < cX).
MaxX = cX;
}.
// Інакше повертаємо «направо «else.
{.
Direct = West; cX—;
// Може це найбільш ліва координата? if (MinX > cX).
MinX = cX;
}.
} break;
// Захід case West:
{.
B = Line[cX];
// Якщо елемент «чорний », повертаємо знову «наліво «if (B < 255).
{.
Direct = South; cY++;
Line = (Byte*)FromImage->ScanLine[cY]; if (MaxY < cY).
MaxY = cY;
}.
// Інакше повертаємо «направо «else.
{.
Direct = North; cY—;
Line = (Byte*)FromImage->ScanLine[cY];
// Може це найбільш верхня точка? if (TopPoint.Y > cY).
{.
TopPoint.Y = cY;
TopPoint.X = cX;
}.
}.
}.
} }.
TopPoint.X++;
if ((!TopPoint.X) && (!TopPoint.Y)) {.
TopPoint.X = X;
TopPoint.Y = Y; } else {.
X = TopPoint. X;
Y = TopPoint. Y; }.
// Будівництво скелета ToLine = (Byte*)ToImage->ScanLine[Y]; ToLine[X] = 0;
// Повертаємо наліво (новий напрям — південь) cX = X; cY = Y;
Vertex.X = X; Vertex. Y = Y; ShapeVector. push_back (Vertex);
Direct = East; Line = (Byte*)FromImage->ScanLine[cY];
// Поки що прийдемо в вихідну точку, виділяємо контур об'єкта do {.
// Залежно від того плинного напрями руху жука switch (Direct).
{.
// Північ case North:
{.
B = Line[cX];
// Якщо елемент «чорний », повертаємо знову «наліво «if (B < 255).
{.
ToLine = (Byte*)ToImage->ScanLine[cY];
ToLine[cX] = 0;
Vertex.X = cX;
Vertex.Y = cY; if (Distance (Vertex, ShapeVector[ShapeVector.size () — 1]) >= Treshold).
ShapeVector.push_back (Vertex);
Direct = West; cX—;
}.
// Інакше повертаємо «направо «else.
{.
Direct = East; cX++;
}.
} break;
// Схід case East:
{.
B = Line[cX];
// Якщо елемент «чорний », повертаємо знову «наліво «if (B < 255).
{.
ToLine = (Byte*)ToImage->ScanLine[cY];
ToLine[cX] = 0;
Vertex.X = cX;
Vertex.Y = cY; if (Distance (Vertex, ShapeVector[ShapeVector.size () — 1]) >= Treshold).
ShapeVector.push_back (Vertex);
Direct = North; cY—;
Line = (Byte*)FromImage->ScanLine[cY];
}.
// Інакше повертаємо «направо «else.
{.
Direct = South; cY++;
Line = (Byte*)FromImage->ScanLine[cY];
}.
} break;
// Південь case South:
{.
B = Line[cX];
// Якщо елемент «чорний », повертаємо знову «наліво «if (B < 255).
{.
ToLine = (Byte*)ToImage->ScanLine[cY];
ToLine[cX] = 0;
Vertex.X = cX;
Vertex.Y = cY; if (Distance (Vertex, ShapeVector[ShapeVector.size () — 1]) >= Treshold).
ShapeVector.push_back (Vertex);
Direct = East; cX++;
}.
// Інакше повертаємо «направо «else.
{.
Direct = West; cX—;
}.
} break;
// Захід case West:
{.
B = Line[cX];
// Якщо елемент «чорний », повертаємо знову «наліво «if (B < 255).
{.
ToLine = (Byte*)ToImage->ScanLine[cY];
ToLine[cX] = 0;
Vertex.X = cX;
Vertex.Y = cY; if (Distance (Vertex, ShapeVector[ShapeVector.size () — 1]) >= Treshold).
ShapeVector.push_back (Vertex);
Direct = South; cY++;
Line = (Byte*)FromImage->ScanLine[cY];
}.
// Інакше повертаємо «направо «else.
{.
Direct = North; cY—;
Line = (Byte*)FromImage->ScanLine[cY];
}.
}.
} } while ((cX ≠ X) || (cY ≠ Y));
Vertex.X = X; Vertex. Y = Y; ShapeVector. push_back (Vertex);
ToImage->Canvas->Pen->Color = clRed; ToImage->Canvas->MoveTo (ShapeVector[0]. X, ShapeVector[0]. Y); for (UINT і = 1; і < ShapeVector. size (); і++) {.
ToImage->Canvas->LineTo (ShapeVector[i]. X, ShapeVector[i]. Y); }.
for (UINT і = 0; і < ShapeVector. size (); і++) {.
ShapeVector[i]. X -= MinX;
ShapeVector[i]. Y -= Y; }.
/*.
if (Symb == «Й ») {.
Symb++; }.
if (Symb == «а ») {.
// Symb = «A »; break; }.
if ((Symb ≠ «И ») && (!SkipMode)) {.
AnsiString FileName = ExtractFilePath (Application->ExeName) + «TPL » ;
FileName += Symb;
ofstream OutFile (FileName.c_str ()); for (UINT і = 0; і < ShapeVector. size (); i++).
{.
OutFile.