6 System.SysUtils, System.Types, System.UITypes, System.Classes,
8 FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.Ani, FMX.Layouts,
9 FMX.Gestures, FMX.Graphics,
10 FMX.TabControl, FMX.StdCtrls, System.Actions, FMX.ActnList, FMX.StdActns,
11 FMX.MediaLibrary.Actions, FMX.Objects, FMX.Controls.Presentation, FMX.Edit,
12 FMX.Media, Unit2, Math, FMX.ListBox;
16 StyleBook1: TStyleBook;
17 ToolbarHolder: TLayout;
19 ToolbarPopupAnimation: TFloatAnimation;
21 ToolbarApplyButton: TButton;
22 ToolbarCloseButton: TButton;
23 ToolbarAddButton: TButton;
24 TabControl1: TTabControl;
41 RadioButton1: TRadioButton;
42 RadioButton2: TRadioButton;
43 CameraComponent1: TCameraComponent;
45 SpinEditButton1: TSpinEditButton;
46 SpinEditButton2: TSpinEditButton;
47 SpinEditButton3: TSpinEditButton;
62 procedure ToolbarCloseButtonClick(Sender: TObject);
63 procedure FormGesture(Sender: TObject; const EventInfo: TGestureEventInfo;
64 var Handled: Boolean);
65 procedure FormKeyDown(Sender: TObject; var Key: Word; var KeyChar: Char;
67 procedure Button1Click(Sender: TObject);
68 procedure Button2Click(Sender: TObject);
69 procedure Button4Click(Sender: TObject);
70 procedure FormCreate(Sender: TObject);
71 procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
72 Shift: TShiftState; X, Y: Single);
73 procedure FormDestroy(Sender: TObject);
74 procedure CameraComponent1SampleBufferReady(Sender: TObject;
76 procedure Button3Click(Sender: TObject);
77 procedure Button5Click(Sender: TObject);
79 FGestureOrigin: TPointF;
80 FGestureInProgress: Boolean;
84 Fourier, recg: TFourier;
87 procedure ShowToolbar(AShow: Boolean);
88 procedure detectImage;
89 procedure recognition;
90 function SingleSortS(item1, item2: TFmxObject): integer;
91 function SingleSortL(item1, item2: TFmxObject): integer;
103 procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; var KeyChar: Char;
106 if Key = vkEscape then
107 ShowToolbar(not ToolbarPopup.IsOpen);
110 procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
111 Shift: TShiftState; X, Y: Single);
117 if Sender = Image1 then
121 with Sender as TImage do
123 Bitmap.BitmapScale := Width / Bitmap.Width;
125 TImage(Sender).Canvas.BeginScene;
126 for i := 0 to s.numEntry - 1 do
128 r := RectF(s.ar[i].Left, s.ar[i].Top, s.ar[i].Right, s.ar[i].Bottom);
129 if (X > r.Left) and (X < r.Right) and (Y > r.Top) and (Y < r.Bottom) then
131 if r.Width < r.Height then
133 rr.Height := r.Height;
134 rr.Width := r.Width * rr.Height / r.Height;
139 rr.Height := r.Height * rr.Width / r.Width;
142 if Sender = Image1 then
144 Image2.Canvas.BeginScene;
145 Image2.Canvas.FillRect(Image2.BoundsRect, 0, 0, [], 1.0);
146 Image2.Canvas.DrawBitmap(Image1.Bitmap, r, rr, 1.0);
147 Image2.Canvas.EndScene;
151 Image3.Canvas.BeginScene;
152 Image3.Canvas.FillRect(Image3.BoundsRect, 0, 0, [], 1);
153 Image3.Canvas.DrawBitmap(Image4.Bitmap, r, rr, 1);
154 Image3.Canvas.EndScene;
159 TImage(Sender).Canvas.EndScene;
160 if Sender = Image1 then
166 procedure TForm1.recognition;
170 a, b: array of Single;
171 estima: array of Single;
172 X, Y, wr, wi: array [0 .. TBoundary.MAX_POINT] of Single;
176 fr, fi, cc, ss: Single;
179 SetLength(a, 4 * recg.numDescriptor);
180 SetLength(b, 4 * recg.numDescriptor);
181 SetLength(estima, recg.numEntry);
182 bnd := recg.boundary[recg.rIndex];
183 test := recg.model[recg.rIndex];
185 for i := 0 to recg.numDescriptor - 1 do
187 test.coReal1[i] := 0;
188 test.coImag1[i] := 0;
189 test.coReal2[i] := 0;
190 test.coImag2[i] := 0;
191 for j := 0 to bnd.Count - 1 do
193 fr := bnd.X[j + 1] - bnd.X[j];
194 fi := bnd.Y[j + 1] - bnd.Y[j];
195 cc := cos(2 * pi * i * j / n);
196 ss := sin(2 * pi * i * j / n);
197 test.coReal1[i] := test.coReal1[i] + fr * cc + fi * ss;
198 test.coImag1[i] := test.coImag1[i] - fr * ss + fi * cc;
199 test.coReal2[i] := test.coReal2[i] + fr * cc - fi * ss;
200 test.coImag2[i] := test.coImag2[i] + fr * ss + fi * cc;
202 test.coReal1[i] := test.coReal1[i] / n;
203 test.coImag1[i] := test.coImag1[i] / n;
204 test.coReal2[i] := test.coReal2[i] / n;
205 test.coImag2[i] := test.coImag2[i] / n;
209 for i := 0 to bnd.Count - 1 do
213 for j := 0 to recg.numDescriptor - 1 do
215 cc := cos(2 * pi * i * j / n);
216 ss := sin(2 * pi * i * j / n);
217 wr[i] := wr[i] + test.coReal1[j] * cc - test.coImag1[j] * ss +
218 test.coReal2[j] * cc + test.coImag2[j] * ss;
219 wi[i] := wi[i] + test.coReal1[j] * ss + test.coImag1[j] * cc -
220 test.coReal2[j] * ss + test.coImag2[j] * cc;
223 Image3.Canvas.BeginScene;
224 Image3.Canvas.FillRect(Image3.BoundsRect, 0, 0, [], 1);
225 Image3.Canvas.DrawRect(Image3.BoundsRect, 0, 0, [], 1);
226 for i := 1 to bnd.Count - 1 do
228 X[i] := X[i - 1] + wr[i - 1];
229 Y[i] := Y[i - 1] + wi[i - 1];
230 Image3.Canvas.DrawLine(PointF(X[i - 1], Y[i - 1]), PointF(X[i], Y[i]), 1);
232 Image3.Canvas.EndScene;
234 for i := 0 to recg.numDescriptor - 1 do
236 a[cnt] := test.coReal1[i];
237 a[recg.numDescriptor + cnt] := test.coImag1[i];
238 a[2 * recg.numDescriptor + cnt] := test.coReal2[i];
239 a[3 * recg.numDescriptor + cnt] := test.coImag2[i];
242 for n := 0 to Fourier.numEntry - 1 do
245 for i := 0 to Fourier.numDescriptor - 1 do
247 b[cnt] := Fourier.model[n].coImag1[i];
248 b[recg.numDescriptor + cnt] := Fourier.model[n].coImag1[i];
249 b[2 * recg.numDescriptor + cnt] := Fourier.model[n].coReal2[i];
250 b[3 * recg.numDescriptor + cnt] := Fourier.model[n].coImag2[i];
253 if RadioButton1.IsChecked = true then
256 for i := 0 to 4 * recg.numDescriptor - 1 do
257 dist := dist + (a[i] - b[i]) * (a[i] - b[i]);
258 estima[n] := Sqrt(dist);
261 estima[n] := recg.Correlation(a, b, 4 * recg.numDescriptor);
263 ListBox1.Items.Clear;
265 for i := 0 to recg.numEntry - 1 do
267 j := ListBox1.Items.Add('(' + Fourier.model[i].name + ')' +
269 ListBox1.ListItems[j].TagFloat := estima[i];
271 if RadioButton1.IsChecked = true then
272 ListBox1.Sort(SingleSortS)
274 ListBox1.Sort(SingleSortL);
275 for i := ListBox1.Items.Count - 1 downto 5 do
276 ListBox1.Items.Delete(i);
282 procedure TForm1.ToolbarCloseButtonClick(Sender: TObject);
284 Application.Terminate;
287 procedure TForm1.Button1Click(Sender: TObject);
289 CameraComponent1.Active := true;
293 procedure TForm1.Button2Click(Sender: TObject);
295 CameraComponent1.Active := false;
297 TabControl1.TabIndex := 0;
300 procedure TForm1.Button3Click(Sender: TObject);
302 Fourier.model[Fourier.rIndex].name := Edit4.Text;
306 procedure TForm1.Button4Click(Sender: TObject);
311 fr, fi, ss, cc: Single;
313 Fourier.numDescriptor := Edit5.Text.ToInteger;
314 if Fourier.numDescriptor > 50 then
316 Fourier.numDescriptor := 50;
319 for i := 0 to Fourier.numEntry - 1 do
321 n := Fourier.boundary[i].Count;
322 for j := 0 to Fourier.numDescriptor - 1 do
324 with Fourier.model[i] do
331 with Fourier.boundary[i] do
337 for k := 0 to n - 1 do
339 fr := Fourier.boundary[i].X[(k + 1) * m] - Fourier.boundary[i].X[k * m];
340 fi := Fourier.boundary[i].Y[(k + 1) * m] - Fourier.boundary[i].Y[k * m];
341 cc := cos(2 * pi * j * k / n);
342 ss := sin(2 * pi * j * k / n);
343 with Fourier.model[i] do
345 coReal1[j] := coReal1[j] + fr * cc + fi * ss;
346 coReal2[j] := coReal2[j] - fr * ss + fi * cc;
347 coImag1[j] := coImag1[j] + fr * cc - fi * ss;
348 coImag2[j] := coImag2[j] + fr * ss + fi * cc;
351 with Fourier.model[i] do
353 coReal1[j] := coReal1[j] / n;
354 coReal2[j] := coReal2[j] / n;
355 coImag1[j] := coImag1[j] / n;
356 coImag2[j] := coImag2[j] / n;
360 thBinary := Edit3.Text.ToInteger;
361 recg.minWidth := Edit1.Text.ToInteger;
362 recg.minHeight := Edit2.Text.ToInteger;
363 Image4.Bitmap.Assign(back);
364 recg.BinaryGray(Image4.Bitmap, thBinary, true);
365 recg.DetectArea(Image4.Bitmap);
366 recg.numDescriptor := Fourier.numDescriptor;
367 TabControl1.TabIndex := 2;
370 procedure TForm1.Button5Click(Sender: TObject);
374 ListBox2.Items.Clear;
375 for i := 0 to Fourier.numEntry - 1 do
376 ListBox2.Items.Add(Fourier.model[i].name + ' / ' + i.ToString);
379 procedure TForm1.CameraComponent1SampleBufferReady(Sender: TObject;
382 CameraComponent1.SampleBufferToBitmap(Image1.Bitmap, true);
385 procedure TForm1.detectImage;
389 bmp.Assign(Image1.Bitmap);
396 thBinary := Edit3.Text.ToInteger;
397 Fourier.minWidth := Edit1.Text.ToInteger;
398 Fourier.minHeight := Edit2.Text.ToInteger;
399 Fourier.BinaryGray(bmp, thBinary, true);
400 Fourier.DetectArea(bmp);
401 Image1.Bitmap.Assign(bmp);
404 function TForm1.SingleSortL(item1, item2: TFmxObject): integer;
408 s := TListBoxItem(item1).TagFloat - TListBoxItem(item2).TagFloat;
417 function TForm1.SingleSortS(item1, item2: TFmxObject): integer;
421 s := TListBoxItem(item1).TagFloat - TListBoxItem(item2).TagFloat;
430 procedure TForm1.FormCreate(Sender: TObject);
432 bmp := TBitmap.Create;
433 buf := TBitmap.Create;
434 back := TBitmap.Create;
435 cap := not Image1.Bitmap.IsEmpty;
436 Fourier := TFourier.Create;
437 Fourier.color := TAlphaColors.Blue;
438 recg := TFourier.Create;
439 recg.color := TAlphaColors.Red;
440 back.Assign(Image4.Bitmap);
443 procedure TForm1.FormDestroy(Sender: TObject);
452 procedure TForm1.FormGesture(Sender: TObject;
453 const EventInfo: TGestureEventInfo; var Handled: Boolean);
457 if EventInfo.GestureID = igiPan then
459 if (TInteractiveGestureFlag.gfBegin in EventInfo.Flags) and
460 ((Sender = ToolbarPopup) or (EventInfo.Location.Y > (ClientHeight - 70)))
463 FGestureOrigin := EventInfo.Location;
464 FGestureInProgress := true;
467 if FGestureInProgress and (TInteractiveGestureFlag.gfEnd in EventInfo.Flags)
470 FGestureInProgress := false;
471 DX := EventInfo.Location.X - FGestureOrigin.X;
472 DY := EventInfo.Location.Y - FGestureOrigin.Y;
473 if (Abs(DY) > Abs(DX)) then
479 procedure TForm1.ShowToolbar(AShow: Boolean);
481 ToolbarPopup.Width := ClientWidth;
482 ToolbarPopup.PlacementRectangle.Rect :=
483 TRectF.Create(0, ClientHeight - ToolbarPopup.Height, ClientWidth - 1,
485 ToolbarPopupAnimation.StartValue := ToolbarPopup.Height;
486 ToolbarPopupAnimation.StopValue := 0;
488 ToolbarPopup.IsOpen := AShow;