mirror of
https://github.com/Laex/Delphi-OpenCV.git
synced 2024-11-16 00:05:52 +01:00
a016c463c5
Signed-off-by: Laentir Valetov <laex@bk.ru>
219 lines
5.8 KiB
ObjectPascal
219 lines
5.8 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.
|
||
//*******************************************************************
|
||
|
||
program cv_CalcOpticalFlowPyrLK;
|
||
|
||
{$APPTYPE CONSOLE}
|
||
{$POINTERMATH ON}
|
||
|
||
{$R *.res}
|
||
|
||
uses
|
||
System.SysUtils,
|
||
ocv.highgui_c,
|
||
ocv.core_c,
|
||
ocv.core.types_c,
|
||
ocv.imgproc_c,
|
||
ocv.imgproc.types_c,
|
||
ocv.tracking_c;
|
||
|
||
const
|
||
MAX_COUNT = 500;
|
||
|
||
var
|
||
image: pIplImage = nil;
|
||
grey: pIplImage = nil;
|
||
prev_grey: pIplImage = nil;
|
||
pyramid: pIplImage = nil;
|
||
prev_pyramid: pIplImage = nil;
|
||
swap_temp: pIplImage;
|
||
win_size: longint = 10;
|
||
corners: pCvPoint2D32f;
|
||
prev_features: pCvPoint2D32f;
|
||
swap_points: pCvPoint2D32f;
|
||
status: array [0 .. MAX_COUNT] of TCVChar;
|
||
count: longint = 0;
|
||
need_to_init: longint = 0;
|
||
night_mode: longint = 0;
|
||
flags: longint = 0;
|
||
add_remove_pt: longint = 0;
|
||
pt: TCvPoint;
|
||
k: longint;
|
||
{ ----------------------- }
|
||
capture: PCvCapture;
|
||
frame: pIplImage;
|
||
|
||
c: Integer;
|
||
|
||
procedure main_cycle();
|
||
var
|
||
cs: TCvSize;
|
||
eig, temp: pIplImage;
|
||
quality, min_distance, dx, dy: double;
|
||
i: Integer;
|
||
begin
|
||
frame := cvQueryFrame(capture);
|
||
if not(assigned(frame)) then
|
||
exit;
|
||
|
||
if not(assigned(image)) then
|
||
begin
|
||
// * allocate all the buffers
|
||
cs.width := frame.width;
|
||
cs.height := frame.height;
|
||
image := cvCreateImage(cs, 8, 3);
|
||
image.Origin := frame.Origin;
|
||
grey := cvCreateImage(cs, 8, 1);
|
||
prev_grey := cvCreateImage(cs, 8, 1);
|
||
pyramid := cvCreateImage(cs, 8, 1);
|
||
prev_pyramid := cvCreateImage(cs, 8, 1);
|
||
flags := 0;
|
||
end;
|
||
|
||
cvCopy(frame, image);
|
||
cvCvtColor(image, grey, CV_BGR2GRAY);
|
||
|
||
if (night_mode = 1) then
|
||
cvZero(image);
|
||
|
||
if (need_to_init = 1) then
|
||
begin
|
||
// * automatic initialization
|
||
eig := cvCreateImage(cvGetSize(grey), 32, 1);
|
||
temp := cvCreateImage(cvGetSize(grey), 32, 1);
|
||
quality := 0.101;
|
||
min_distance := 10.0;
|
||
|
||
count := MAX_COUNT;
|
||
cvGoodFeaturesToTrack(grey, eig, temp, corners, @count, quality, min_distance, nil, 3, 0, 0.04);
|
||
cvFindCornerSubPix(grey, corners, count, cvsize(win_size, win_size), cvsize(-1, -1),
|
||
cvTermCriteria(CV_TERMCRIT_ITER or CV_TERMCRIT_EPS, 20, 0.03));
|
||
cvReleaseImage(eig);
|
||
cvReleaseImage(temp);
|
||
|
||
add_remove_pt := 0;
|
||
end
|
||
else if (count > 0) then
|
||
begin
|
||
cvCalcOpticalFlowPyrLK(prev_grey, grey, prev_pyramid, pyramid, prev_features, corners, count,
|
||
cvsize(win_size, win_size), 3, @status, nil, cvTermCriteria(CV_TERMCRIT_ITER or CV_TERMCRIT_EPS, 20,
|
||
0.03), flags);
|
||
flags := flags or CV_LKFLOW_PYR_A_READY;
|
||
|
||
k := 0;
|
||
for i := 0 to count - 1 do
|
||
begin
|
||
if (add_remove_pt = 1) then
|
||
begin
|
||
dx := pt.x - corners[i].x;
|
||
dy := pt.y - corners[i].y;
|
||
|
||
if (dx * dx + dy * dy <= 25) then
|
||
begin
|
||
add_remove_pt := 0;
|
||
continue;
|
||
end;
|
||
end;
|
||
|
||
if (status[i] = #0) then
|
||
continue;
|
||
|
||
corners[k] := corners[i];
|
||
inc(k);
|
||
cvCircle(image, cvPointFrom32f(corners[i]), 3, CV_RGB(0, 255, 0), -1, 8, 0);
|
||
end;
|
||
count := k;
|
||
end;
|
||
|
||
if ((add_remove_pt = 1) and (count < MAX_COUNT)) then
|
||
begin
|
||
corners[count] := cvPointTo32f(pt);
|
||
inc(count);
|
||
// newpoint -> points[1] + count - 1
|
||
// newpoint := corners[count - 1];
|
||
cvFindCornerSubPix(grey, @corners[count - 1], 1, cvsize(win_size, win_size), cvsize(-1, -1),
|
||
cvTermCriteria(CV_TERMCRIT_ITER or CV_TERMCRIT_EPS, 20, 0.030));
|
||
add_remove_pt := 0;
|
||
end;
|
||
|
||
CV_SWAP(prev_grey, grey, swap_temp);
|
||
CV_SWAP(prev_pyramid, pyramid, swap_temp);
|
||
CV_SWAP(prev_features, corners, swap_points);
|
||
|
||
need_to_init := 0;
|
||
{ visualize the camera image in the window }
|
||
cvShowImage('LkDemo', image);
|
||
end;
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> c<><63><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>
|
||
procedure myMouseCallback(event: Integer; x: Integer; y: Integer; flags: Integer; param: pointer); cdecl;
|
||
begin
|
||
if assigned(image) then
|
||
case event of
|
||
CV_EVENT_MOUSEMOVE:
|
||
;
|
||
CV_EVENT_LBUTTONDOWN:
|
||
begin
|
||
pt := cvPoint(x, y);
|
||
add_remove_pt := 1;
|
||
end;
|
||
CV_EVENT_LBUTTONUP:
|
||
;
|
||
end;
|
||
end;
|
||
|
||
begin
|
||
try
|
||
capture := cvCreateCameraCapture(CV_CAP_ANY);
|
||
Assert(assigned(capture));
|
||
cvNamedWindow('LkDemo', CV_WINDOW_AUTOSIZE);
|
||
cvSetMouseCallback('LkDemo', myMouseCallback);
|
||
|
||
corners := AllocMem(SizeOf(TCvPoint2D32f) * MAX_COUNT);
|
||
prev_features := AllocMem(SizeOf(TCvPoint2D32f) * MAX_COUNT);
|
||
|
||
while true do
|
||
begin
|
||
main_cycle;
|
||
c := cvWaitKey(33);
|
||
if c = 27 then
|
||
Break;
|
||
if c = Ord('r') then
|
||
need_to_init := 1;
|
||
if c = Ord('c') then
|
||
count := 0;
|
||
if c = Ord('n') then
|
||
night_mode := night_mode xor 1;
|
||
end;
|
||
|
||
cvReleaseCapture(capture);
|
||
cvReleaseImage(image);
|
||
cvDestroyAllWindows;
|
||
|
||
except
|
||
on E: Exception do
|
||
Writeln(E.ClassName, ': ', E.Message);
|
||
end;
|
||
|
||
end.
|