mirror of
https://github.com/Laex/Delphi-OpenCV.git
synced 2024-11-15 15:55:53 +01:00
b83b5a010f
Signed-off-by: Laentir Valetov <laex@bk.ru>
199 lines
6.0 KiB
ObjectPascal
199 lines
6.0 KiB
ObjectPascal
(*
|
|
*****************************************************************
|
|
Delphi-OpenCV 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.
|
|
*******************************************************************
|
|
*)
|
|
|
|
// Example 10-2. Kalman filter sample code
|
|
//
|
|
// Use Kalman Filter to model particle in circular trajectory.
|
|
(* *************** License:**************************
|
|
Oct. 3, 2008
|
|
Right to use this code in any way you want without warrenty, support or any guarentee of it working.
|
|
|
|
BOOK: It would be nice if you cited it:
|
|
Learning OpenCV: Computer Vision with the OpenCV Library
|
|
by Gary Bradski and Adrian Kaehler
|
|
Published by O'Reilly Media, October 3, 2008
|
|
|
|
AVAILABLE AT:
|
|
http://www.amazon.com/Learning-OpenCV-Computer-Vision-Library/dp/0596516134
|
|
Or: http://oreilly.com/catalog/9780596516130/
|
|
ISBN-10: 0596516134 or: ISBN-13: 978-0596516130
|
|
|
|
OTHER OPENCV SITES:
|
|
* The source code is on sourceforge at:
|
|
http://sourceforge.net/projects/opencvlibrary/
|
|
* The OpenCV wiki page (As of Oct 1, 2008 this is down for changing over servers, but should come back):
|
|
http://opencvlibrary.sourceforge.net/
|
|
* An active user group is at:
|
|
http://tech.groups.yahoo.com/group/OpenCV/
|
|
* The minutes of weekly OpenCV development meetings are at:
|
|
http://pr.willowgarage.com/wiki/OpenCV
|
|
************************************************** *)
|
|
|
|
program ch10_ex10_2;
|
|
|
|
{$APPTYPE CONSOLE}
|
|
{$POINTERMATH ON}
|
|
{$R *.res}
|
|
|
|
uses
|
|
System.SysUtils,
|
|
ocv.utils,
|
|
ocv.core_c,
|
|
ocv.highgui_c,
|
|
ocv.core.types_c,
|
|
ocv.imgproc.types_c,
|
|
ocv.imgproc_c,
|
|
ocv.tracking_c,
|
|
ocv.compat,
|
|
uResourcePaths;
|
|
|
|
function phi2xy(const img: PIplImage; const mat: PCvMat): TcvPoint;
|
|
begin
|
|
Result := cvPoint(cvRound(img^.width / 2 + img^.width / 3 * cos(pFloat(mat^.data)[0])),
|
|
cvRound(img^.height / 2 - img^.width / 3 * sin(pFloat(mat^.data)[0])))
|
|
end;
|
|
|
|
Var
|
|
|
|
CVX_RED: TCvScalar;
|
|
CVX_GREEN: TCvScalar;
|
|
CVX_BLUE: TCvScalar;
|
|
|
|
CVX_CYAN: TCvScalar;
|
|
CVX_MAGENTA: TCvScalar;
|
|
CVX_YELLOW: TCvScalar;
|
|
|
|
CVX_WHITE: TCvScalar;
|
|
CVX_BLACK: TCvScalar;
|
|
CVX_GRAY50: TCvScalar;
|
|
|
|
rng: TCvRandState;
|
|
img: PIplImage;
|
|
kalman: PCvKalman;
|
|
x_k: PCvMat;
|
|
w_k: PCvMat;
|
|
z_k: PCvMat;
|
|
F: array [0 .. 3] of Single;
|
|
y_k: PCvMat;
|
|
|
|
begin
|
|
try
|
|
// Init CVX
|
|
CVX_RED := CV_RGB($FF, $00, $00);
|
|
CVX_GREEN := CV_RGB($00, $FF, $00);
|
|
CVX_BLUE := CV_RGB($00, $00, $FF);
|
|
|
|
CVX_CYAN := CV_RGB($00, $FF, $FF);
|
|
CVX_MAGENTA := CV_RGB($FF, $00, $FF);
|
|
CVX_YELLOW := CV_RGB($FF, $FF, $00);
|
|
|
|
CVX_WHITE := CV_RGB($FF, $FF, $FF);
|
|
CVX_BLACK := CV_RGB($00, $00, $00);
|
|
CVX_GRAY50 := CV_RGB($88, $88, $88);
|
|
|
|
// Initialize, create Kalman Filter object, window, random number
|
|
// generator etc.
|
|
//
|
|
cvNamedWindow('Kalman', 1);
|
|
cvRandInit(@rng, 0, 1, -1, CV_RAND_UNI);
|
|
|
|
img := cvCreateImage(cvSize(500, 500), 8, 3);
|
|
kalman := cvCreateKalman(2, 1, 0);
|
|
// state is (phi, delta_phi) - angle and angular velocity
|
|
// Initialize with random guess.
|
|
//
|
|
x_k := cvCreateMat(2, 1, CV_32FC1);
|
|
cvRandSetRange(@rng, 0, 0.1, 0);
|
|
rng.disttype := CV_RAND_NORMAL;
|
|
cvRand(@rng, x_k);
|
|
|
|
// process noise
|
|
//
|
|
w_k := cvCreateMat(2, 1, CV_32FC1);
|
|
|
|
// measurements, only one parameter for angle
|
|
//
|
|
z_k := cvCreateMat(1, 1, CV_32FC1);
|
|
cvZero(z_k);
|
|
|
|
// Transition matrix 'F' describes relationship between
|
|
// model parameters at step k and at step k+1 (this is
|
|
// the 'dynamics' in our model.
|
|
//
|
|
F[0] := 1;
|
|
F[1] := 1;
|
|
F[2] := 0;
|
|
F[3] := 1;
|
|
Move(F, kalman^.transition_matrix^.data.ptr^, sizeof(F));
|
|
// Initialize other Kalman filter parameters.
|
|
//
|
|
cvSetIdentity(kalman^.measurement_matrix, cvRealScalar(1));
|
|
cvSetIdentity(kalman^.process_noise_cov, cvRealScalar(1E-5));
|
|
cvSetIdentity(kalman^.measurement_noise_cov, cvRealScalar(1E-1));
|
|
cvSetIdentity(kalman^.error_cov_post, cvRealScalar(1));
|
|
|
|
// choose random initial state
|
|
//
|
|
cvRand(@rng, kalman^.state_post);
|
|
|
|
while True do
|
|
begin
|
|
// predict point position
|
|
y_k := cvKalmanPredict(kalman^, 0);
|
|
|
|
// generate measurement (z_k)
|
|
//
|
|
cvRandSetRange(@rng, 0, sqrt(pFloat(kalman^.measurement_noise_cov^.data)[0]), 0);
|
|
cvRand(@rng, z_k);
|
|
cvMatMulAdd(kalman^.measurement_matrix, x_k, z_k, z_k);
|
|
// plot points (eg convert to planar co-ordinates and draw)
|
|
//
|
|
cvZero(img);
|
|
cvCircle(img, phi2xy(img, z_k), 4, CVX_YELLOW); // observed state
|
|
cvCircle(img, phi2xy(img, y_k), 4, CVX_WHITE, 2); // 'predicted' state
|
|
cvCircle(img, phi2xy(img, x_k), 4, CVX_RED); // real state
|
|
cvShowImage('Kalman', img);
|
|
// adjust Kalman filter state
|
|
//
|
|
cvKalmanCorrect(kalman^, z_k);
|
|
|
|
// Apply the transition matrix 'F' (eg, step time forward)
|
|
// and also apply the 'process' noise w_k.
|
|
//
|
|
cvRandSetRange(@rng, 0, sqrt(pFloat(kalman^.process_noise_cov^.data)[0]), 0);
|
|
cvRand(@rng, w_k);
|
|
cvMatMulAdd(kalman^.transition_matrix, x_k, w_k, x_k);
|
|
|
|
// exit if user hits 'Esc'
|
|
if (cvWaitKey(100) = 27) then
|
|
break;
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
Writeln(E.ClassName, ': ', E.Message);
|
|
end;
|
|
|
|
end.
|