Delphi-OpenCV/samples/MultiDemo/HandsDetect/HandsDetect2.dpr

193 lines
6.2 KiB
ObjectPascal
Raw Normal View History

// *****************************************************************
// 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.
// *******************************************************************
// Original: http://anikettatipamula.blogspot.ro/2012/02/hand-gesture-using-opencv.html
// *******************************************************************
program HandsDetect2;
{$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;
procedure detect(const img_8uc1: pIplImage; const img_8uc3: pIplImage);
Var
storage: pCvMemStorage;
first_contour: pCvSeq;
maxitem: pCvSeq;
area, areamax: Double;
maxn: Integer;
Nc: Integer;
n: Integer;
c: pCvSeq;
storage3: pCvMemStorage;
pt0: TCvPoint;
storage1, storage2: pCvMemStorage;
ptseq: pCvSeq;
hull, defects: pCvSeq;
i, j: Integer;
p: pCvPoint;
hullcount: Integer;
defectArray: pCvConvexityDefect;
nomdef: Integer;
font: TCvFont;
txt: AnsiString;
begin
// 8uc1 is BW image with hand as white And 8uc3 is the original image
storage := cvCreateMemStorage(0);
first_contour := AllocMem(SizeOf(TCvSeq));
maxitem := nil;
area := 0;
areamax := 0;
maxn := 0;
// function to find the white objects in the image and return the object boundaries
Nc := cvFindContours(img_8uc1, storage, @first_contour, SizeOf(TCvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE,
cvPoint(0, 0));
// Try all four values and see what happens
n := 0;
WriteLn('Total Contours Detected: ', Nc);
// Here we find the contour with maximum area
if (Nc > 0) then
begin
c := first_contour;
While c <> nil do
begin
// cvCvtColor( img_8uc1, img_8uc3, CV_GRAY2BGR );
area := Abs(cvContourArea(c, CV_WHOLE_SEQ));
if (area > areamax) then
begin
areamax := area;
maxitem := c;
maxn := n;
c := c^.h_next;
end;
Inc(n);
end;
storage3 := cvCreateMemStorage(0);
if (areamax > 5000) then // check for area greater than certain value and find convex hull
begin
maxitem := cvApproxPoly(maxitem, SizeOf(TCvContour), storage3, CV_POLY_APPROX_DP, 10, 1);
storage1 := cvCreateMemStorage(0);
storage2 := cvCreateMemStorage(0);
ptseq := cvCreateSeq(CV_SEQ_KIND_GENERIC or CV_32SC2, SizeOf(TCvContour), SizeOf(TCvPoint), storage1);
for i := 0 to maxitem^.total - 1 do
begin
p := CV_GET_SEQ_ELEM(SizeOf(TCvPoint), maxitem, i);
pt0.x := p^.x;
pt0.y := p^.y;
cvSeqPush(ptseq, @pt0);
end;
hull := cvConvexHull2(ptseq, nil, CV_CLOCKWISE, 0);
hullcount := hull^.total;
defects := cvConvexityDefects(ptseq, hull, storage2);
WriteLn('cvConvexityDefects total ', defects^.total);
// int m_nomdef:=0;
// This cycle marks all defects of convexity of current contours.
While Assigned(defects) do
begin
nomdef := defects^.total; // defect amount
// outlet_float( m_nomdef, nomdef );
WriteLn('defect no ', nomdef);
if (nomdef = 0) then
begin
defects := defects^.h_next;
continue;
end;
// Alloc memory for defect set.
// fprintf(stderr,'malloc');
defectArray := AllocMem(SizeOf(TCvConvexityDefect) * nomdef);
// Get defect set.
// fprintf(stderr,'cvCvtSeqToArray');
cvCvtSeqToArray(defects, defectArray, CV_WHOLE_SEQ);
// Draw marks for all defects.
for i := 0 to nomdef - 1 do
begin
WriteLn('Defect depth for defect ', i:4, defectArray[i].depth:10:3);
cvLine(img_8uc3, defectArray[i].start^, defectArray[i].depth_point^, CV_RGB(255, 255, 0), 1, CV_AA, 0);
cvCircle(img_8uc3, defectArray[i].depth_point^, 5, CV_RGB(0, 0, 164), 2, 8, 0);
cvCircle(img_8uc3, defectArray[i].start^, 5, CV_RGB(0, 0, 164), 2, 8, 0);
cvLine(img_8uc3, defectArray[i].depth_point^, defectArray[i]._end^, CV_RGB(255, 255, 0), 1, CV_AA, 0);
end;
txt := '0' + IntToStr(nomdef - 1);
cvInitFont(@font, CV_FONT_HERSHEY_SIMPLEX, 1.0, 1.0, 0, 5, CV_AA);
cvPutText(img_8uc3, PAnsiChar(@txt[1]), cvPoint(50, 50), @font, cvScalar(0, 0, 255, 0));
Inc(j);
// Free memory.
freemem(defectArray);
defects := defects^.h_next;
end;
cvReleaseMemStorage(storage);
cvReleaseMemStorage(storage1);
cvReleaseMemStorage(storage2);
cvReleaseMemStorage(storage3);
end;
end;
end;
Var
capture: PCvCapture;
frame: pIplImage;
image: pIplImage = nil;
gray_image: pIplImage = nil;
begin
try
capture := cvCreateCameraCapture(CV_CAP_ANY);
cvNamedWindow('capture', CV_WINDOW_AUTOSIZE);
while true do
begin
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
frame := cvQueryFrame(capture);
image := cvCloneImage(frame);
gray_image := cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);
cvCvtColor(image, gray_image, CV_RGB2GRAY);
detect(gray_image, image);
cvShowImage('capture', image);
cvReleaseImage(image);
cvReleaseImage(gray_image);
if cvWaitKey(33) = 27 then
Break;
end;
cvReleaseCapture(capture);
cvDestroyWindow('capture');
except
on E: Exception do
WriteLn(E.ClassName, ': ', E.Message);
end;
end.