Структура базы для хранения эталонных символов

Код символа Эталонная строка
   

 

Код символа - однозначно идентифицирует хранимый символ. Так как в базе хранятся эталоны иероглифов, для которых в русском алфавите нет примера начертания, то для замены распознанного символа нужно еще хранить и его эталонное изображение. Но так как целью данной работы является не замена распознанных символов на эталонные, а только соотнесение с эталоном, то для экономии дискового пространства решено хранить не эталонное изображение символа, а только его уникальный код, с помощью которого можно однозначно идентифицировать символ.

Эталонная строка - строка, содержащая в себе все 9 плотностей выделенной области.

 

 

Текст программы

 

{$I CdBase.inc}

{$I CdComp.inc}

unit Main;

 

interface

 

uses

SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,

Forms, Dialogs, Reg_imag, Menus, Options, CmplSign, DBTables, DB;

 

type

TMainForm = class(TForm)

MainMenu: TMainMenu;

N1: TMenuItem;

N2: TMenuItem;

Image: TMultiImage;

N3: TMenuItem;

NFileOpen: TMenuItem;

OpenDialog: TOpenDialog;

NSelect: TMenuItem;

N4: TMenuItem;

N5: TMenuItem;

N6: TMenuItem;

N7: TMenuItem;

Onemore1: TMenuItem;

N8: TMenuItem;

N9: TMenuItem;

DataTable: TTable;

N10: TMenuItem;

DataTableOpis: TStringField;

DataTableID: TFloatField;

procedure N2Click(Sender: TObject);

procedure NFileOpenClick(Sender: TObject);

procedure NSelectClick(Sender: TObject);

procedure FormCreate(Sender: TObject);

procedure ImageMouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

procedure ImageMouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

procedure ImageMouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

procedure N4Click(Sender: TObject);

procedure N7Click(Sender: TObject);

procedure Onemore1Click(Sender: TObject);

procedure N8Click(Sender: TObject);

procedure N9Click(Sender: TObject);

procedure N5Click(Sender: TObject);

procedure N10Click(Sender: TObject);

private

DetectRectX, DetectRectY: real; { Угол, под которым выделять линии }

xStart, xEnd, yStart, yEnd: word;

BegSelect: boolean;

procedure DefGradient(var Gx, Gy: real; x,y: word);

procedure SetRect;

procedure DefPlotn;

procedure AfinConvert;

procedure OneMore;

procedure Mandel;

procedure Paporotnik;

function GetDensity: string;

public

{ Public declarations }

end;

 

var

MainForm: TMainForm;

 

implementation

{$R *.DFM}

 

procedure TMainForm.N2Click(Sender: TObject);

begin

Application.Terminate;

end;

 

procedure TMainForm.NFileOpenClick(Sender: TObject);

begin

if OpenDialog.Execute then begin

Image.ImageName:= OpenDialog.FileName;

NSelect.Enabled:= True;

end

else NSelect.Enabled:= False;

end;

 

procedure TMainForm.NSelectClick(Sender: TObject);

var

Result: word;

begin

OptionForm:= nil;

try

OptionForm:= TOptionForm.Create(Self);

with OptionForm do begin

RectXEdit.Text:= FloatToStr(DetectRectX);

RectYEdit.Text:= FloatToStr(DetectRectY);

X1Edit.Text:= IntToStr(xStart);

X2Edit.Text:= IntToStr(xEnd);

Y1Edit.Text:= IntToStr(yStart);

Y2Edit.Text:= IntToStr(yEnd);

Result:= ShowModal;

DetectRectX:= StrToInt(RectXEdit.Text);

DetectRectY:= StrToInt(RectYEdit.Text);

xStart:= StrToInt(X1Edit.Text);

xEnd:= StrToInt(X2Edit.Text);

yStart:= StrToInt(Y1Edit.Text);

yEnd:= StrToInt(Y2Edit.Text);

end; { with }

finally

OptionForm.Free;

end; { try }

if Result = mrOK then SetRect;

end;

 

{ Определение градиентов Gx и Gy в точке [x,y] }

procedure TMainForm.DefGradient(var Gx, Gy: real; x,y: word);

var

a, b, c, d, e, g, h, i: byte;

begin

with Image.Canvas do begin

if Pixels[x-1,y-1] = clBlack then a:= 0

else a:= 1;

if Pixels[x,y-1] = clBlack then b:= 0

else b:= 1;

if Pixels[x+1,y-1] = clBlack then c:= 0

else c:= 1;

if Pixels[x-1,y] = clBlack then d:= 0

else d:= 1;

if Pixels[x+1,y] = clBlack then e:= 0

else e:= 1;

if Pixels[x-1,y+1] = clBlack then g:= 0

else g:= 1;

if Pixels[x,y+1] = clBlack then h:= 0

else h:= 1;

if Pixels[x+1,y+1] = clBlack then i:= 0

else i:= 1;

{ Градиент по X }

Gx:= g + 2*h + i - a - 2*b - c;

if Gx < 0 then Gx:= 0;

if Gx = 0 then Gx:= 0.000001;

{ Градиент по Y }

Gy:= c + 2*e + i - a - 2*d - g;

if Gy < 0 then Gy:= 0;

end; { with Image }

end;

 

procedure TMainForm.SetRect;

var

x, y: word;

Gx, Gy, Qx, Qy: real;

OutF: TextFile;

S1,S2: string;

begin

AssignFile(OutF, 'tangs.000');

Rewrite(OutF);

{ Сканируем все изображение }

with Image.Canvas do begin

for y:= yStart+1 to yEnd-1 do begin

for x:= xStart+1 to xEnd-1 do begin

   DefGradient(Gx,Gy,x,y); { Определить градиент в точке [x,y] }

   {if Gx+Gy > 0 then Pixels[x,y+200]:= clRed;}

 

   Qx:= ArcTan(Gy/Gx);

   Qx:= Round(Qx*180/Pi);

{ Qx:= Round(90*Gx/4);

   Qy:= Round(90*Gy/4);}

   Str(Qx:2:0, S1);

{   Str(Qy:2:0, S2); }

   Write(OutF, S1+{' '+S2+}' | ');

{ if (Q <= -Pi/3) or (Q >= Pi/3) then Pixels[x,y+200]:= clRed;}

   if (Qx > { DetectRectX}80) and (Qx < 100){ and (Q > DetectRect*Pi/180) }then

     Pixels[x,y+200]:= clRed;

end; { for x }

WriteLn(OutF, 'End Line');

end; { for y }

end; { with Image.Canvas }

CloseFile(OutF);

end;

 

 

procedure TMainForm.DefPlotn;

var

i, j, x, y, dx, dy, Range, x1, y1: word;

Count: word;

begin

x:= xStart; y:= yStart;

dx:= Round((xEnd-xStart+1) div 3);

dy:= Round((yEnd-yStart+1) div 3);

x1:= x; y1:= y;

{ Три квадрата по вертикали }

for i:= 1 to 3 do begin

if i = 2 then Range:= (yEnd-yStart+1) - 2*dy

else Range:= dy;

{ Три квадрата по горизонтали }

for j:= 1 to 3 do begin

if j = 2 then Range:= (xEnd-xStart+1) - 2*dx

else Range:= dx;

{ Сканируем внутри квадрата по y }

    for y:= y1 to y1+Range do begin

   { Сканируем внутри квадрата по x }

   for x:= x1 to x1+Range do begin

     { Подсчитываем число не белых пикселов }

     if Image.Canvas.Pixels[x,y] <> clWhite then Inc(Count);

   end; { for x }

end; { for y }

x1:= x1+dx;          { Следующий квадрат по горизонтали }

end; { for j }

y1:= y1+dy;              { Следующий квадрат по вертикали }

end; { for i }

end;

 

procedure TMainForm.FormCreate(Sender: TObject);

begin

OpenDialog.FileName:= 'c:\delphi\mydir\diplom\pict\pict1.bmp';

Image.ImageName:= OpenDialog.FileName;

end;

 

procedure TMainForm.ImageMouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

if Button = mbRight then begin

Image.ImageName:= OpenDialog.FileName;

Exit;

end;

BegSelect:= True;

with Image.Canvas do begin

Pen.Mode:= pmXor;

Pen.Color:= clGreen;

Pen.Style:= psDot;

Brush.Style:= bsClear;

xStart:= X; yStart:= Y;

xEnd:= X; yEnd:= Y;

end; { with }

end;

 

procedure TMainForm.ImageMouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

BegSelect:= False;

with Image.Canvas do begin

Pen.Mode:= pmCopy;

Pen.Color:= clBlack;

Pen.Style:= psSolid;

Brush.Style:= bsSolid;

end; { with }

end;

 

procedure TMainForm.ImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);

begin

if not BegSelect then Exit;

with Image.Canvas do begin

Rectangle(xStart, yStart, xEnd, yEnd);

xEnd:= X; yEnd:= Y;

Rectangle(xStart, yStart, xEnd, yEnd);

end; { with }

end;

 

procedure TMainForm.N4Click(Sender: TObject);

begin

Image.ImageName:= OpenDialog.FileName;

end;

 

 

{ Афинное преобразование }

procedure TMainForm.AfinConvert;

var

dx, dy, Rand: word;

A, B, C, D, E, F: real;

x, y: word;

i: longint;

begin

A:= 0.5; B:= 0.5; E:= 0;

C:= 0.3; D:= 0; F:= 1;

 

dx:= (xEnd-xStart+1) div 2; xEnd:= xStart +2*dx - 1;

dy:= (yEnd-yStart+1) div 2; yEnd:= yStart +2*dy - 1;

 

x:= xStart+dx; y:= yStart+dy;

Randomize;

for i:= 1 to 50000 do begin

Rand:= Random(10);

Case Rand of

0..3: begin

         x:= xStart + 1 + (x-xStart+1) div 2;

      y:= yStart + 1 + (y-yStart+1) div 2;

    end;

4: begin

      x:= xStart + dx + (x-xStart+1) div 2;

      y:= yStart + 1 + (y-yStart+1) div 2;

    end;

5: begin

        x:= xStart + 1 + (x-xStart+1) div 2;

      y:= yStart + dy + (y-yStart+1) div 2;

    end;

6..9: begin

      x:= xStart + dx + (x-xStart+1) div 2;

      y:= yStart + dy + (y-yStart+1) div 2;

    end;

end; { Case }

 

Image.Canvas.Pixels[x,y]:= clBlue;

end; { for i }

end;

 

 

procedure TMainForm.N7Click(Sender: TObject);

begin

AfinConvert;

end;

 

 

procedure TMainForm.OneMore;

var

dx, dy, Rand, Kx, Ky: word;

A, B, C, D, E, F: real;

x, y, K: real;

i: longint;

begin

Kx:= 4; Ky:= 4;

dx:= (xEnd-xStart+1) div Kx; xEnd:= xStart +Kx*dx - 1;

dy:= (yEnd-yStart+1) div Ky; yEnd:= yStart +Ky*dy - 1;

x:= xStart; y:= yStart;

for i:= 1 to 100000 do begin

Rand:= Random(Kx*Ky);

if (Rand = 0) or (Rand = 3) or (Rand = 12) or (Rand = 15) then

Continue;

 

K:= (Rand - Kx*(Rand div Kx)) *dx;

x:= K + xStart + 1 + (x-xStart+1) / Kx;

K:= (Rand div Kx)*dy;

y:= K + yStart + 1 + (y-yStart+1) / Ky;

 

Image.Canvas.Pixels[Round(x),Round(y)]:= clBlue;

end; { for i }

end;

 

 

procedure TMainForm.Onemore1Click(Sender: TObject);

begin

OneMore;

end;

 

 

procedure TMainForm.Mandel;

var

Z, Z0, C: TComplex;

i, x, y: word;

begin

Z0:= TComplex.Create(0,0);

Z:= TComplex.Create(0,0);

C:= TComplex.Create(0,0);

for y:= yStart to yEnd do begin

for x:= xStart to xEnd do begin

C.Assign(x,y);

Z.Mul(Z0);

Z.Plus(C);

if (Z.Re < 2) and (Z.Im < 2) then

   Image.Canvas.Pixels[Z.Re,Z.Im]:= clBlue;

Z.Assign(0,0);

end; { for x }

end; { for y }

C.Free;

Z.Free;

Z0.Free;

end;

 

 

procedure TMainForm.N8Click(Sender: TObject);

begin

Mandel;

end;

 

procedure TMainForm.Paporotnik;

const

A: array[0..3, 0..2, 0..3] of integer =

                           (((0,0,0,0),(0,20,0,0),(0,0,0,0)),

                            ((85,0,0,0),(0,85,11,70),(0,-10,85,0)),

                            ((31,-41,0,0),(10,21,0,21),(0,0,30,0)),

                            ((-29,40,0,0),(10,19,0,56),(0,0,30,0)));

var

b: array[1..15000] of word;

k, n, i: word;

newX, newY, z, x, y: real;

Color: longint;

begin

x:= 0; y:= 0; z:= 0;

Randomize;

for k:= 1 to 15000 do begin

b[k]:= Random(10);

if b[k] > 3 then b[k]:= 1;

end; { for k }

 

i:= 1;

{ b[i]:= 1;}

for i:= 1 to 10000 do begin

newX:= (a[b[i],0,0]*x + a[b[i],0,1]*y + a[b[i],0,2]*z) / 100+

        a[b[i],0,3];

newY:= (a[b[i],1,0]*x + a[b[i],1,1]*y + a[b[i],1,2]*z) / 100+

        a[b[i],1,3];

z:= (a[b[i],2,0]*x + a[b[i],2,1]*y + a[b[i],2,2]*z) / 100+

        a[b[i],2,3];

x:= newX; y:= newY;

Color:= Random(65535);

Color:= Color*100;

Image.Canvas.Pixels[Round(300-x+z), Round(350-y)]:= clGreen;

end; { for k }

end;

 

 

procedure TMainForm.N9Click(Sender: TObject);

begin

Paporotnik;

end;

 

function TMainForm.GetDensity: string;

var

i, j: byte;

LenX, LenY, x, y, xOld, yOld, dx, dy: word;

BlackCnt, TotCnt: word;

P: real;                      { Плотность пикселов в квадранте }

S, S1: string;

begin

{ Определяем плотность в 9 квадрантах }

{ выделенного диапазона }

S:= '';

LenX:= xEnd-xStart+1;

LenY:= yEnd-yStart+1;

xOld:= xStart; yOld:= yStart;

for j:= 1 to 3 do begin

if j = 2 then dy:= LenY-2*Round(LenY/3)

else dy:= Round(LenY/3);

for i:= 1 to 3 do begin

if i = 2 then dx:= LenX-2*Round(LenX/3)

else dx:= Round(LenX/3);

{------------------------------------------------------------------}

BlackCnt:= 0;     { Кол-во черных пикселов в квадранте }

for y:= yOld to yOld+dy-1 do begin

   for x:= xOld to xOld+dx-1 do begin

     if Image.Canvas.Pixels[x,y] <> clWhite then Inc(BlackCnt);

   end; { for x }

end; { for y }

{------------------------------------------------------------------}

TotCnt:= dx*dy;

P:= BlackCnt/TotCnt;  { Плотность пикселов в квадранте }

Str(P:1:3, S1);

S:= S+S1+' ';

xOld:= xOld+dx;

end; { for i }

yOld:= yOld+dy;

end; { for j }

Result:= S;

end; { TMainForm.GetDensity }

 

procedure TMainForm.N5Click(Sender: TObject);

var

S: string;

ID: word;

begin

S:= GetDensity;

ID:= DataTable.RecordCount;

DataTable.AppendRecord([ID+1, S]);

end;

 

procedure TMainForm.N10Click(Sender: TObject);

var

SValue: string[5];

S, DStr1, DStr2, OldS: string;

Value, NewValue: real;

i: byte;

ID: word;

begin

S:= GetDensity;

OldS:= S;

DataTable.First;

Value:= 100;

ID:= 0;

while not DataTable.EOF do begin

NewValue:= 0;

{-----------------------------------------------------------}

for i:= 1 to 9 do begin

  DStr1:= Copy(S, (i-1)*6+1, 5);

  DStr2:= Copy(DataTableOpis.Value, (i-1)*6+1, 5);

  NewValue:= NewValue + Abs(StrToFloat(DStr2)-StrToFloat(DStr1));

end; { for i }

{-----------------------------------------------------------}

if NewValue < Value then begin

Value:= NewValue;

ID:= DataTableID.AsInteger;

end;

DataTable.Next;

end; { while }

ShowMessage(IntToStr(ID));

end;

end.


[1] Известно, что при создании обычными средствами (”руками”) интерфейса пользователя для программ, работающих в графических средах, на это уходит более 80% времени разработки приложения.



Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: