mirror of
https://github.com/Laex/Delphi-OpenCV.git
synced 2024-11-16 16:25:53 +01:00
236 lines
5.4 KiB
ObjectPascal
236 lines
5.4 KiB
ObjectPascal
|
// *****************************************************************
|
||
|
// Delphi-OpenCV Class Demo
|
||
|
// Copyright (C) 2013 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
|
||
|
// ****************************************************************
|
||
|
// The contents of this file are used with permission, 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/MPL-1_1Final.html
|
||
|
//
|
||
|
// 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.
|
||
|
// *******************************************************************
|
||
|
// Original:
|
||
|
// http://docs.opencv.org/modules/ml/doc/k_nearest_neighbors.html#cvknearest-is-regression
|
||
|
// *******************************************************************
|
||
|
|
||
|
program Class_2D_Point_Classification;
|
||
|
|
||
|
{$APPTYPE CONSOLE}
|
||
|
{$POINTERMATH ON}
|
||
|
{$R *.res}
|
||
|
|
||
|
uses
|
||
|
System.SysUtils,
|
||
|
System.Classes,
|
||
|
Core.types_c,
|
||
|
core_c,
|
||
|
highgui_c,
|
||
|
ml;
|
||
|
|
||
|
Const
|
||
|
K10: Integer = 10;
|
||
|
|
||
|
Var
|
||
|
i, j, K, accuracy : Integer;
|
||
|
response : float;
|
||
|
train_sample_count: Integer = 100;
|
||
|
rng_state : TCvRNG;
|
||
|
trainData : pCvMat;
|
||
|
trainClasses : pCvMat;
|
||
|
img : pIplImage;
|
||
|
_sample : array [0 .. 1] of float;
|
||
|
sample : TCvMat;
|
||
|
trainData1, //
|
||
|
trainData2, //
|
||
|
trainClasses1, //
|
||
|
trainClasses2: TCvMat;
|
||
|
knn : ICvKNearest;
|
||
|
nearests : pCvMat;
|
||
|
t : TCvScalar;
|
||
|
pt : TCvPoint;
|
||
|
|
||
|
begin
|
||
|
try
|
||
|
rng_state := CvRNG(-1);
|
||
|
trainData := cvCreateMat(
|
||
|
train_sample_count,
|
||
|
2,
|
||
|
CV_32FC1);
|
||
|
trainClasses := cvCreateMat(
|
||
|
train_sample_count,
|
||
|
1,
|
||
|
CV_32FC1);
|
||
|
img := cvCreateImage(
|
||
|
cvSize(500, 500),
|
||
|
8,
|
||
|
3);
|
||
|
sample := CvMat(
|
||
|
1,
|
||
|
2,
|
||
|
CV_32FC1,
|
||
|
@_sample);
|
||
|
cvZero(img);
|
||
|
// form the training samples
|
||
|
cvGetRows(
|
||
|
trainData,
|
||
|
@trainData1,
|
||
|
0,
|
||
|
train_sample_count div 2);
|
||
|
cvRandArr(
|
||
|
@rng_state,
|
||
|
@trainData1,
|
||
|
CV_RAND_NORMAL,
|
||
|
cvScalar(200, 200),
|
||
|
cvScalar(50, 50));
|
||
|
|
||
|
cvGetRows(
|
||
|
trainData,
|
||
|
@trainData2,
|
||
|
train_sample_count div 2,
|
||
|
train_sample_count);
|
||
|
cvRandArr(
|
||
|
@rng_state,
|
||
|
@trainData2,
|
||
|
CV_RAND_NORMAL,
|
||
|
cvScalar(300, 300),
|
||
|
cvScalar(50, 50));
|
||
|
|
||
|
cvGetRows(
|
||
|
trainClasses,
|
||
|
@trainClasses1,
|
||
|
0,
|
||
|
train_sample_count div 2);
|
||
|
cvSet(
|
||
|
@trainClasses1,
|
||
|
cvScalar(1));
|
||
|
|
||
|
cvGetRows(
|
||
|
trainClasses,
|
||
|
@trainClasses2,
|
||
|
train_sample_count div 2,
|
||
|
train_sample_count);
|
||
|
cvSet(
|
||
|
@trainClasses2,
|
||
|
cvScalar(2));
|
||
|
|
||
|
// learn classifier
|
||
|
knn := CreateCvKNearest(
|
||
|
trainData,
|
||
|
trainClasses,
|
||
|
nil,
|
||
|
false,
|
||
|
K10);
|
||
|
nearests := cvCreateMat(
|
||
|
1,
|
||
|
K10,
|
||
|
CV_32FC1);
|
||
|
|
||
|
for i := 0 to img^.height - 1 do
|
||
|
begin
|
||
|
for j := 0 to img^.width - 1 do
|
||
|
begin
|
||
|
pFloat(sample.data)[0] := j;
|
||
|
pFloat(sample.data)[1] := i;
|
||
|
// estimate the response and get the neighbors' labels
|
||
|
response := knn.find_nearest(
|
||
|
@sample,
|
||
|
K10,
|
||
|
nil,
|
||
|
nil,
|
||
|
nearests,
|
||
|
nil);
|
||
|
|
||
|
// compute the number of neighbors representing the majority
|
||
|
accuracy := 0;
|
||
|
for K := 0 to K10 - 1 do
|
||
|
begin
|
||
|
if (pFloat(nearests^.data)[K] = response) then
|
||
|
Inc(accuracy);
|
||
|
end;
|
||
|
// highlight the pixel depending on the accuracy (or confidence)
|
||
|
if response = 1 then
|
||
|
begin
|
||
|
if accuracy > 5 then
|
||
|
t := CV_RGB(
|
||
|
180,
|
||
|
0,
|
||
|
0)
|
||
|
else
|
||
|
CV_RGB(
|
||
|
180,
|
||
|
120,
|
||
|
0);
|
||
|
end
|
||
|
else
|
||
|
begin
|
||
|
if accuracy > 5 then
|
||
|
t := CV_RGB(
|
||
|
0,
|
||
|
180,
|
||
|
0)
|
||
|
else
|
||
|
CV_RGB(
|
||
|
120,
|
||
|
120,
|
||
|
0);
|
||
|
end;
|
||
|
cvSet2D(
|
||
|
img,
|
||
|
i,
|
||
|
j,
|
||
|
t);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
// display the original training samples
|
||
|
for i := 0 to (train_sample_count div 2) - 1 do
|
||
|
begin
|
||
|
pt.x := cvRound(pFloat(trainData1.data)[i * 2]);
|
||
|
pt.y := cvRound(pFloat(trainData1.data)[i * 2 + 1]);
|
||
|
cvCircle(
|
||
|
img,
|
||
|
pt,
|
||
|
2,
|
||
|
CV_RGB(255, 0, 0),
|
||
|
CV_FILLED);
|
||
|
pt.x := cvRound(pFloat(trainData2.data)[i * 2]);
|
||
|
pt.y := cvRound(pFloat(trainData2.data)[i * 2 + 1]);
|
||
|
cvCircle(
|
||
|
img,
|
||
|
pt,
|
||
|
2,
|
||
|
CV_RGB(0, 255, 0),
|
||
|
CV_FILLED);
|
||
|
end;
|
||
|
|
||
|
cvNamedWindow(
|
||
|
'classifier result',
|
||
|
1);
|
||
|
cvShowImage(
|
||
|
'classifier result',
|
||
|
img);
|
||
|
cvWaitKey(0);
|
||
|
|
||
|
cvReleaseMat(trainClasses);
|
||
|
cvReleaseMat(trainData);
|
||
|
except
|
||
|
on E: Exception do
|
||
|
WriteLn(
|
||
|
E.ClassName,
|
||
|
': ',
|
||
|
E.Message);
|
||
|
end;
|
||
|
|
||
|
end.
|