2008年10月15日水曜日

QCのパッチ / OpenCVのFaceDetecotrを入れてみる(再度)...

追記(2009/3/1):入出力の扱いはこっちがただしいかも.

追記(2009/2/15):
コロッと書くのを忘れていたが,出力部に関してはこちらを参照のこと!


先日のQRコードネタFaceDetector側も修正してみた.

#import <Quartz/Quartz.h>
#include <cv.h>
@interface OpenCV_FaceDetectorPlugIn : QCPlugIn
{
CvHaarClassifierCascade *cascade;
IplImage *src_img;
int prevW;
int prevH;

}
@property(assign) id<QCPlugInInputImageSource> inputSourceImage;
@property double outputHeight;
@property double outputWidth;
@property double outputY;
@property double outputX;
@property BOOL outputHasFound;

@end
...
@implementation OpenCV_FaceDetectorPlugIn
@dynamic inputSourceImage;
@dynamic outputHeight, outputWidth, outputY, outputX;
@dynamic outputHasFound;

...
- (id) init
{
if(self = [super init]) {
cascade= nil;
src_img= nil;
prevW= 0;
prevH= 0;

}
return self;
}...
- (BOOL) startExecution:(id<QCPlugInContext>)context
{
NSBundle* mainBundle = [NSBundle bundleWithIdentifier:@"com.yourcompany.OpenCV_FaceDetector"];
const char *cascade_name = [[mainBundle pathForResource:@"haarcascade_frontalface_default" ofType:@"xml"] UTF8String];
cascade = (CvHaarClassifierCascade *) cvLoad (cascade_name, 0, 0, 0);

return YES;
}
...
- (BOOL) execute:(id<QCPlugInContext>)context atTime:(NSTimeInterval)time withArguments:(NSDictionary*)arguments
{
id<QCPlugInInputImageSource> image= self.inputSourceImage;
if (!image) {
return YES;
}

[image lockBufferRepresentationWithPixelFormat:QCPlugInPixelFormatBGRA8
colorSpace:[image imageColorSpace]
forBounds:[image imageBounds]];
{
if (src_img==nil
|| prevW!=[image bufferPixelsWide]
|| prevH!=[image bufferPixelsHigh]){
if (src_img!=nil) {
cvReleaseImage(&src_img);
}
src_img= cvCreateImage(cvSize([image bufferPixelsWide], [image bufferPixelsHigh]), IPL_DEPTH_8U, 4);
prevW= [image bufferPixelsWide];
prevH= [image bufferPixelsHigh];
}
src_img->imageData= [image bufferBaseAddress];
//src_img->imageDataOrigin= [image bufferBaseAddress];


IplImage *src_gray = cvCreateImage (cvGetSize (src_img), IPL_DEPTH_8U, 1);
CvMemStorage *storage = cvCreateMemStorage (0);
cvClearMemStorage (storage);
cvCvtColor (src_img, src_gray, CV_BGRA2GRAY);
cvEqualizeHist (src_gray, src_gray);
CvSeq *faces = cvHaarDetectObjects (src_gray, cascade, storage, 1.11, 4, 0, cvSize (40, 40));
int i;
double resultA= 0.0;
CvRect *resultR;
for (i = 0; i < (faces ? faces->total : 0); i++) {
CvRect *r = (CvRect *) cvGetSeqElem (faces, i);
double tmpA= r->width * r->height;
if (resultA<tmpA) {
resultA= tmpA;
resultR= r;
}
}

self.outputHasFound= NO;
if (resultA>0.0) {
self.outputHasFound= YES;
self.outputX= resultR->x;
self.outputY= resultR->y;
self.outputWidth= resultR->width;
self.outputHeight= resultR->height;
}


cvReleaseImage (&src_gray);
cvReleaseMemStorage (&storage);

}
[image unlockBufferRepresentation];

return YES;
}
...
- (void) stopExecution:(id<QCPlugInContext>)context
{
if (src_img!=nil) {
cvReleaseImage(&src_img);
}

}
@end

一応,
イタリック体はIplImageを利用するための記述.
ボールド体は顔検出パッチ用の記述
というつもり.

追加ライブラリは
libcv.dylib, libcxcore.dylib
である.
追加リソースは
haarcascade_frontalface_default.xml (/opt/local/share/opencv/haarcascades/haarcascade_frontalface_default.xml)
である.
プロジェクトのインスペクタで以下を設定した.
アーキテクチャ/アーキテクチャ: Native Architecture of Build Machine
検索パス/ヘッダ検索パス: /opt/local/include/opencv


opencvをportで入れると/opt/local以下に入る.入れ方はこう
> sudo port install opencv


間違いをご指摘いただければ幸いです.

0 件のコメント: