#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#define NEED_newRV_noinc
#define NEED_sv_2pv_nolen
#include "ppport.h"
#include "cv.h"
#include "highgui.h"
MODULE = Image::ObjectDetect PACKAGE = Image::ObjectDetect
PROTOTYPES: ENABLE
SV *
new(class, cascade_name)
SV *class;
char *cascade_name;
PREINIT:
CvHaarClassifierCascade *cascade;
SV *self;
CODE:
cascade = cvLoad(cascade_name, 0, 0, 0);
if (!cascade)
croak("Can't load the cascade file");
self = newSViv(PTR2IV(cascade));
self = newRV_noinc(self);
sv_bless(self, gv_stashpv(SvPV_nolen(class), 1));
RETVAL = self;
OUTPUT:
RETVAL
SV *
xs_detect(self, filename)
SV *self;
char *filename;
PREINIT:
IplImage *img, *gray;
int i;
CvMemStorage *storage;
CvHaarClassifierCascade *cascade;
CvSeq *objects;
CvRect *rect;
AV *retval;
HV *hash;
CODE:
img = cvLoadImage(filename, 1);
if (!img)
croak("Can't load the image file");
gray = cvCreateImage(cvSize(img->width, img->height), 8, 1);
cvCvtColor(img, gray, CV_BGR2GRAY);
cvEqualizeHist(gray, gray);
storage = cvCreateMemStorage(0);
cascade = INT2PTR(CvHaarClassifierCascade *, SvIV(SvRV(self)));
objects = cvHaarDetectObjects(gray, cascade, storage,
#if (CV_MAJOR_VERSION < 2 || (CV_MAJOR_VERSION == 2 && CV_MINOR_VERSION < 1))
1.1, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(0, 0));
#else
1.1, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(0, 0), cvSize(0, 0));
#endif
retval = newAV();
for (i = 0; i < (objects ? objects->total : 0); i++) {
rect = (CvRect *) cvGetSeqElem(objects, i);
hash = newHV();
hv_store(hash, "x", 1, newSViv(rect->x), 0);
hv_store(hash, "y", 1, newSViv(rect->y), 0);
hv_store(hash, "width", 5, newSViv(rect->width), 0);
hv_store(hash, "height", 6, newSViv(rect->height), 0);
av_push(retval, newRV_noinc((SV *) hash));
}
cvReleaseMemStorage(&storage);
cvReleaseImage(&img);
cvReleaseImage(&gray);
RETVAL = newRV_noinc((SV *) retval);
OUTPUT:
RETVAL
void
DESTROY(self)
SV *self;
PREINIT:
CvHaarClassifierCascade *cascade;
CODE:
cascade = INT2PTR(CvHaarClassifierCascade *, SvIV(SvRV(self)));
cvReleaseHaarClassifierCascade(&cascade);