9

I'm interested in face detection and I'm trying to use OpenCV for my Delphi application. I'm going to use Google Picasa for facial recognition later. And I've found 4 different basic haar cascades for detecting frontal faces:

haarcascade_frontalface_default.xml
haarcascade_frontalface_alt.xml
haarcascade_frontalface_alt2.xml
haarcascade_frontalface_alt_tree.xml

The 'default' haarcascade gives too many false positives and is not good at all, while the 'alt', 'alt2' and 'tree' cascades seem to produce quite accurate, but sometimes different, results. The 'tree' cascade tends to produce more false negatives than the 'alt' and 'alt2' ones, but the least false positives as well.

The problem is that there're two different formats for these haarcascade xml files.

First like this: https://github.com/Danukeru/FOUCAM/blob/master/haarcascade_frontalface.xml

And second like this: https://github.com/Itseez/opencv/blob/master/data/haarcascades/haarcascade_frontalface_alt.xml

If I'm not mistaken, the second one is considered the 'new' format, but my app currently understands only the first 'old' format. The 'new' cascades can probably be more accurate and I'd like to give them a try.

Is there any way to convert the new format cascades to an old format?

Or how else can I use them in my app?

Here's some code (from sites.google.com/site/josejp1/index/OCV.ZIP):

f1 := 'haarcascade_frontalface_alt.xml';
file1 := PChar(f1);
cascade_f := cvLoad(file1,0,0,0);
storage := cvCreateMemStorage(0);

s.width := 40;
s.height := 40;
faces := cvHaarDetectObjects(PCvArr(img), cascade_f, storage, 1.1, 3, 0, s);

And if I try to use the 'new' format xml cascade file I get an error:

OpenCV GUI Error Handler
---------------------------
Unspecified error (The node does not represent a user object (unknown type?))
in function cvRead, ..\..\cxcore\src\cxpersistence.cpp(5061)

I haven't found any ready-to-use examples in Delphi with new C++ API so I've converted this example of detectMultiScale (a C++ version of cvHaarDetectObjects) to Delphi. It compiles but crashes when tries to load a cascade. Im new to C++ so any help would be appreciated.

Delphi 2010 project in zip archive

unit Unit1;

interface

uses
  Windows,
  Messages,
  SysUtils,
  Variants,
  Classes,
  Graphics,
  Controls,
  Forms,
  Dialogs,
  StdCtrls,
  ExtCtrls,
  DateUtils,
  ExtDlgs,
  highgui_c,
  core_c,
  Core.types_c,
  imgproc_c,
  imgproc.types_c,
  objdetect;

type
  TForm1 = class(TForm)
    Image1: TImage;
    Button2: TButton;
    Label1: TLabel;
    Memo1: TMemo;
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
    mystorage: pCvMemStorage = nil;
    mycascade : pCvHaarClassifierCascade = nil;
    mycascade_name: AnsiString = 'cascades\haarcascade_frontalface_alt.xml';

implementation

{$R *.dfm}

procedure TForm1.Button2Click(Sender: TObject);

var img, grayImage : PIplImage;
    myobjects : TArray<TCvRect>;
    myscale : double;
    i: integer;
    r: pCvRect;
    mycolors : array[0..7] of TCvScalar;
    myCascadeClassifier : TCascadeClassifier;

begin

   mycolors[0] := CvScalar(0,0,255);
   mycolors[1] := CvScalar(0,128,255);
   mycolors[2] := CvScalar(0,255,255);
   mycolors[3] := CvScalar(0,255,0);
   mycolors[4] := CvScalar(255,128,0);
   mycolors[5] := CvScalar(255,255,0);
   mycolors[6] := CvScalar(255,0,0);
   mycolors[7] := CvScalar(255,0,255);

   img := cvLoadImage('lena.jpg');
   grayImage := cvCreateImage(cvGetSize(img),8,1);
   cvCvtColor(img,grayImage,CV_BGR2GRAY);
   cvShowImage('gray', grayImage);
   mystorage := cvCreateMemStorage(0);

   Memo1.Lines.Add('Memory allocated');

   mycascade := cvLoad('cascade.xml');
   myscale := 1.3;

   cvClearMemStorage(mystorage);
   myobjects := nil;
   myCascadeClassifier.detectMultiScale(grayImage,myobjects,1.1,3,CV_HAAR_SCALE_IMAGE or CV_HAAR_DO_CANNY_PRUNING,cvSize(0,0),cvSize(40,40));

   Memo1.Lines.Add('Object size? : ' + IntToStr(Length(myobjects)));

   for i := 0 to (Length(myobjects)-1) do
    begin
      cvRectangle(grayImage,cvPoint(r.x,r.y),cvPoint(r.x+r.width,r.y+r.height),CvScalar(0,0,255));
    end;

   cvNamedWindow('Output');
   cvShowImage('Output', grayImage);

   cvReleaseImage(grayImage);
   cvReleaseImage(img);

end;

end.

@TLama: I'm using the newest version of Delphi-OpenCV for this project with detectMultiScale, and some outdated (but working) version for the first project with cvHaarDetectObjects mentioned in the first post (sites.google.com/site/josejp1/index/OCV.ZIP).

Community
  • 1
  • 1
FelisManulus
  • 440
  • 4
  • 18
  • Which version of Delphi-OpenCV are you using ? The current commit notes show "Migration to version 2.4.8" which is the most recent version of OpenCV available at this time. So it seems that Delphi-OpenCV should be up to date. Is the version of Delphi-OpenCV you're using also up to date ? – TLama Jan 25 '14 at 19:21
  • 1
    if you want my 2 ct, the developer of the delphi wrapper is living under a rock. even if it supports 2.4.8, it seems to be build on the c-api, which is no more maintained since 4 years already, and will be phased out in the *very* near future – berak Jan 25 '14 at 20:31
  • Did you finally find a way using the new C++ API with Delphi (>= XE)? – menjaraz Mar 24 '15 at 13:31
  • if you can do some changes on source code of OpenCV and rebuild dlls. you could use C++ API with delphi. i will try to show soon. – sturkmen May 02 '16 at 20:15

1 Answers1

5

if those delphi bindings are using the outdated c-api, (cvHaarDetectObjects) - you can only use the old format.

the c++ api ( cv::CascadeClassifier ) supports both, as well as hog and lbp cascades.

again, it's a limitation of the old c-api. if you can, avoid it !

berak
  • 39,159
  • 9
  • 91
  • 89