スタック オーバーフロー コーダーの皆さん、こんにちは。
私は最近、iPhone で OpenCV をいじっていましたが、壁にぶつかったので、あなたに助けを求めています。私はUIKit、Objective Cに精通しており、デスクトップコンピューター上のOpenframeworks C++フレームワークでブロブ検出と顔追跡にOpenCVを使用しました。現在、リアルタイムのビデオ ストリームで顔追跡を機能させようとしています。
単一の画像を使用して、このチュートリアルとサンプルコードから顔検出を行っています: http://niw.at/articles/2009/03/14/using-opencv-on-iphone/en
そして、チュートリアルとサンプル コード (および Apple の例) から OpenGL を使用してウィンドウに表示されるビデオ バッファー出力からデータを正常に取得しましたが、実際にはリンクを見つけることができません (見つけ次第投稿します)。それ)。
didOutputSampleBufferからIPLImageを作成し、標準のopenCVEdgeDetectを使用して画面に表示することにより、ビデオバッファ出力を使用してiPhoneで動作するビデオストリームのedgeDetectionを取得することができました。
しかし、顔検出を機能させることができません。試してみましたが、立ち往生しています。現在、標準のopenCVFaceDetectメソッドに渡されたサンプルバッファから単一の画像を取得し、その画像を顔の周りに正方形(または任意のマーカー)で表示しようとしています。それが機能するようになったら、完全なビデオ ストリームを試してみます。
アプリをクラッシュさせる関数に IPLImage が渡されると、openCV マジックが実行され、このイメージがデリゲート関数に渡されて表示されます。
- (void) opencvFaceDetect:(IplImage *)aTempOverlayImage {
cvSetErrMode(CV_ErrModeParent);
IplImage *aOverlayImage = aTempOverlayImage;//[self CreateIplImageFromUIImage:imageView.image];
// Scaling down
IplImage *small_image = cvCreateImage(cvSize(aOverlayImage->width/2,aOverlayImage->height/2), IPL_DEPTH_8U, 3);
cvPyrDown(aOverlayImage, small_image,CV_GAUSSIAN_5x5);
// Load XML
NSString *path = [[NSBundle mainBundle] pathForResource:@"haarcascade_frontalface_default" ofType:@"xml"];
CvHaarClassifierCascade* cascade = (CvHaarClassifierCascade*)cvLoad([path cStringUsingEncoding:NSASCIIStringEncoding], NULL, NULL, NULL);
CvMemStorage* storage = cvCreateMemStorage(0);
// Detect faces and draw rectangle on them
CvSeq* faces = cvHaarDetectObjects(small_image, cascade, storage, 1.2f, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(20, 20));
cvReleaseImage(&small_image);
[self.delegate parseOpenCVFaces:faces];
// Create canvas to show the results
CGImageRef imageRef = [self getCGImageFromCVImage:aOverlayImage];//imageViewFromOpenCV.image.CGImage;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef contextRef = CGBitmapContextCreate(NULL, 360, 480,
8, 480 * 4,
colorSpace, kCGImageAlphaPremultipliedLast|kCGBitmapByteOrderDefault);
CGContextDrawImage(contextRef, CGRectMake(0, 0, 360, 480), imageRef);
CGContextSetLineWidth(contextRef, 4);
CGContextSetRGBStrokeColor(contextRef, 0.0, 0.0, 1.0, 0.5);
int scale = 2;
// Draw results on the iamge
for(int i = 0; i < faces->total; i++) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
// Calc the rect of faces
CvRect cvrect = *(CvRect*)cvGetSeqElem(faces, i);
CGRect face_rect = CGContextConvertRectToDeviceSpace(contextRef, CGRectMake(cvrect.x * scale, cvrect.y * scale, cvrect.width * scale, cvrect.height * scale));
CGContextStrokeRect(contextRef, face_rect);
[pool release];
}
imageViewFromOpenCV.image = [UIImage imageWithCGImage:CGBitmapContextCreateImage(contextRef)];
[self.delegate parseOpenCVFaceImage:imageViewFromOpenCV.image];
CGContextRelease(contextRef);
CGColorSpaceRelease(colorSpace);
cvReleaseMemStorage(&storage);
cvReleaseHaarClassifierCascade(&cascade);
}
次のエラーが表示されます: Thread 1: Program received signal:"SIGABRT"
at 行:
cvPyrDown(aOverlayImage, small_image,CV_GAUSSIAN_5x5);
私はopenCVのソースコードを見てきましたが、このコードは分析される前に画像を縮小してぼかしているようです。より多くの知識を持っている人からのより良い説明が欲しいのですが(私は多数のGoogle検索を行いました). このコードをコメントアウトすると、関数の閉じ括弧で別の同様のエラーが発生します。
私はこれを正しい方法で行っていますか?人々がこれを機能させ、他の多くの人々がこれを助けたいと思っていることを私は知っています. これに関するアドバイスやヘルプをいただければ幸いです。
ありがとう。