Delphi-OpenCV/samples/VCLDemo/vclPCArecognition/uMainForm.pas
Laex a0967207c1 Add sample PCA recognition (vcl)
Signed-off-by: Laex <laex@bk.ru>
2013-09-15 16:02:26 +04:00

387 lines
10 KiB
ObjectPascal
Raw Blame History

// **************************************************************************************************
// Project Delphi-OpenCV
// **************************************************************************************************
// Contributor:
// Laentir Valetov
// email:laex@bk.ru
// **************************************************************************************************
// You may retrieve the latest version of this file at the GitHub,
// located at git://github.com/Laex/Delphi-OpenCV.git
// **************************************************************************************************
// License:
// The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License");
// you may not use this file except in compliance with the License. You may obtain a copy of the
// License at http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
// ANY KIND, either express or implied. See the License for the specific language governing rights
// and limitations under the License.
//
// Alternatively, the contents of this file may be used under the terms of the
// GNU Lesser General Public License (the "LGPL License"), in which case the
// provisions of the LGPL License are applicable instead of those above.
// If you wish to allow use of your version of this file only under the terms
// of the LGPL License and not to allow others to use your version of this file
// under the MPL, indicate your decision by deleting the provisions above and
// replace them with the notice and other provisions required by the LGPL
// License. If you do not delete the provisions above, a recipient may use
// your version of this file under either the MPL or the LGPL License.
//
// For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html
// **************************************************************************************************
// The Initial Developer of the Original Code:
// OpenCV: open source computer vision library
// Homepage: http://opencv.org
// Online docs: http://docs.opencv.org
// Q&A forum: http://answers.opencv.org
// Dev zone: http://code.opencv.org
// **************************************************************************************************
// Original: https://sites.google.com/site/komputernoezrenie/end
// **************************************************************************************************
{$POINTERMATH ON}
unit uMainForm;
interface
uses
Winapi.Windows,
Winapi.Messages,
System.SysUtils,
System.Variants,
System.Classes,
Vcl.Graphics,
Vcl.Controls,
Vcl.Forms,
Vcl.Dialogs,
Vcl.StdCtrls;
type
TMainForm = class(TForm)
btn1: TButton;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
procedure btn1Click(Sender: TObject);
private
public
end;
var
MainForm: TMainForm;
implementation
{$R *.dfm}
Uses
core_c,
highgui_c,
core.types_c,
legacy,
cvUtils;
procedure TMainForm.btn1Click(Sender: TObject);
const
N_Samples = 7; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Type
TArrayOfpIplImage = pIplImage;
pArrayOfpIplImage = ^TArrayOfpIplImage;
TArrayOfFloat = array [0 .. 0] of Float;
pArrayOfFloat = ^TArrayOfFloat;
ppArrayOfFloat = ^pArrayOfFloat;
Var
img_load : pIplImage;
img_load_ch1: array [0 .. N_Samples - 1] of pIplImage;
test_img: pIplImage;
mean_img : pIplImage; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>)
result_img : pIplImage; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
size : TCvSize;
i, j : Integer;
facesfilename: AnsiString;
Tc : TCvTermCriteria;
nEigens : Integer;
eig_img : Array Of pIplImage;
EigenVals : pCvMat;
min_val, max_val : double;
coeffs : Array Of array of Float;
projectedTestFace: Array Of Float;
leastDistSq : double;
iTrain, iNearest : Integer;
distSq : double;
d_i : Float;
k : Integer;
begin
mean_img := nil; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>)
result_img := nil; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// ****************************************
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
// ****************************************
for i := 0 to N_Samples - 1 do
begin
facesfilename := 'faces/s' + IntToStr(i + 1) + '/1.pgm';
img_load := cvLoadImage(c_str(facesfilename));
size := cvSize(
img_load.width,
img_load.height);
img_load_ch1[i] := cvCreateImage(
size,
IPL_DEPTH_8U,
1);
cvSplit(
img_load,
img_load_ch1[i],
nil,
nil,
nil);
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>
ipDraw(
10 + (size.width + 10) * i,
50,
img_load,
Handle);
end;
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> :)
Label1.Left := (10 + (size.width + 10) * N_Samples - Label1.width) div 2;
Label1.Visible := true;
Label2.Top := (50 + (size.height + 10) - 5);
Label2.Left := (10 + (size.width + 10) + (size.width + 10) * (N_Samples - 1) - Label2.width) div 2;
Label2.Visible := true;
Label3.Top := (50 + (size.height + 20) * 3 - 15);
Label3.Left := (10 + (size.width + 10) + (size.width + 10) * (N_Samples - 1) - Label3.width) div 2;
Label3.Visible := true;
Label4.Top := (50 + (size.height + 20) * 2 - 15);
Label4.Left := (10 + (size.width + 10) + (size.width + 10) * (N_Samples - 1) - Label4.width) div 2;
Label4.Visible := true;
//
// ****************************************
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// ****************************************
i := 3; // <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
facesfilename := 'faces/s' + IntToStr(i + 1) + '/2.pgm';
img_load := cvLoadImage(c_str(facesfilename));
test_img := cvCreateImage(
size,
IPL_DEPTH_8U,
1);
cvSplit(
img_load,
test_img,
nil,
nil,
nil);
ipDraw(
10 + ((size.width + 10) * (N_Samples - 1)) div 2,
50 + (size.height + 20) * 2,
img_load,
Handle);
// ****************************************
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// ****************************************
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
if not Assigned(mean_img) then
begin
mean_img := cvCreateImage(
size,
IPL_DEPTH_32F,
1);
end;
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if not Assigned(result_img) then
begin
result_img := cvCreateImage(
size,
IPL_DEPTH_8U,
1);
end;
// -----------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// -----------------------------------
Tc.cType := CV_TERMCRIT_NUMBER or CV_TERMCRIT_EPS;
// <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>)
Tc.max_iter := 100;
Tc.epsilon := 0.001;
// -----------------------------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> = <20><><EFBFBD>-<2D><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - 1
// -----------------------------------------------------
nEigens := N_Samples - 1;
// <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
SetLength(
eig_img,
nEigens);
EigenVals := cvCreateMat(
1,
nEigens,
IPL_DEPTH_32F);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
for i := 0 to N_Samples - 1 do
begin
eig_img[i] := cvCreateImage(
size,
IPL_DEPTH_32F,
1);
end;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
cvCalcEigenObjects(
N_Samples,
@img_load_ch1[0],
eig_img,
CV_EIGOBJ_NO_CALLBACK,
0,
0,
@Tc,
mean_img,
pFloat(EigenVals.data));
// ****************************************
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>)
// ****************************************
for j := 0 to nEigens - 1 do
begin
cvMinMaxLoc(
eig_img[j],
@min_val,
@max_val);
if (min_val <> max_val) then
begin
cvConvertScale(
eig_img[j],
result_img,
255.0 / (max_val - min_val),
-min_val);
ipDraw(
10 + (size.width + 10) * j + (size.width + 10) div 2,
50 + (size.height + 20),
result_img,
Handle);
end;
end;
// -----------------------------------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// -----------------------------------------------------------
SetLength(
coeffs,
N_Samples);
for i := 0 to N_Samples - 1 do
begin
SetLength(
coeffs[i],
nEigens);
cvEigenDecomposite(
img_load_ch1[i],
nEigens,
@eig_img[0],
CV_EIGOBJ_NO_CALLBACK,
0,
mean_img,
@coeffs[i][0]);
end;
// -----------------------------------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// -----------------------------------------------------------
SetLength(
projectedTestFace,
nEigens);
cvEigenDecomposite(
test_img,
nEigens,
eig_img,
CV_EIGOBJ_NO_CALLBACK,
0,
mean_img,
@projectedTestFace[0]);
// -----------------------------------------------------------
leastDistSq := DBL_MAX;
iTrain := 0;
iNearest := 0;
for iTrain := 0 to N_Samples - 1 do
begin
distSq := 0;
for i := 0 to nEigens - 1 do
begin
d_i := projectedTestFace[i] - coeffs[iTrain][i];
distSq := distSq + d_i * d_i / pFloat(EigenVals.data)[i];
end;
if distSq < leastDistSq then
begin
leastDistSq := distSq;
iNearest := iTrain;
end;
end;
// ****************************************
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
// ****************************************
// APIDrawIpl(10+(10+size.width),50+(size.height+20)*2,img_load_ch1[iNearest],Form1.Handle);
for i := 0 to N_Samples - 1 do
begin
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>
if (i <> iNearest) then
begin
cvLine(
img_load_ch1[i],
cvPoint(0, 0),
cvPoint(size.width, size.height),
CV_RGB(255, 0, 0),
3,
8);
cvLine(
img_load_ch1[i],
cvPoint(size.width, 0),
cvPoint(0, size.height),
CV_RGB(255, 0, 0),
3,
8);
end;
ipDraw(
10 + (size.width + 10) * i,
50 + (size.height + 20) * 3,
img_load_ch1[i],
Handle);
end;
// ****************************************
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// ****************************************
for k := 0 to N_Samples - 1 do
begin
cvReleaseImage(eig_img[k]);
cvReleaseImage(img_load_ch1[k]);
end;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// for i := 0 to N_Samples - 1 do
// begin
// FreeMem(coeffs[i]);
// end;
// delete coeffs;
cvReleaseImage(img_load);
cvReleaseImage(mean_img);
cvReleaseImage(test_img);
cvReleaseImage(result_img);
end;
end.