1

AVCaptureSession を使用して、iPhone のカメラから画像を受信します。デリゲート関数で画像を返します。この関数では、画像を作成し、他のスレッドを呼び出してこの画像を処理します。

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection{
    //    static bool isFirstTime = true;
    //    if (isFirstTime == false) {
    //        return;
    //    }
    //    isFirstTime = false;

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);

    //Lock the image buffer
    CVPixelBufferLockBaseAddress(imageBuffer,0);

    //Get information about the image
    uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer);
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
    size_t width = CVPixelBufferGetWidth(imageBuffer);
    size_t height = CVPixelBufferGetHeight(imageBuffer);

    //Create a CGImageRef from the CVImageBufferRef
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef newContext = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst/*kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast*/);
    CGImageRef newImage = CGBitmapContextCreateImage(newContext);

    // release some components
    CGContextRelease(newContext);
    CGColorSpaceRelease(colorSpace);

    UIImage* uiimage = [UIImage imageWithCGImage:newImage scale:1.0 orientation:UIImageOrientationDown];
    CGImageRelease(newImage);
    CVPixelBufferUnlockBaseAddress(imageBuffer,0);

    //[self performSelectorOnMainThread:@selector(setImageForImageView:) withObject:uiimage waitUntilDone:YES];
    if(processImageThread == nil || (processImageThread != nil && processImageThread.isExecuting == false)){
        [processImageThread release];
        processImageThread = [[NSThread alloc] initWithTarget:self selector:@selector(processImage:) object:uiimage];
        [processImageThread start];
    }

    [pool drain];
}

別のスレッドで画像を処理し、CIFilters を使用します。

- (void) processImage:(UIImage*)image{
    NSLog(@"Begin process");
    CIImage* ciimage = [CIImage imageWithCGImage:image.CGImage];
    CIFilter* filter = [CIFilter filterWithName:@"CIColorMonochrome"];// keysAndValues:kCIInputImageKey, ciimage, "inputRadius", [NSNumber numberWithFloat:10.0f], nil];
    [filter setDefaults];
    [filter setValue:ciimage forKey:@"inputImage"];
    [filter setValue:[CIColor colorWithRed:0.5 green:0.5 blue:1.0] forKey:@"inputColor"];
    CIImage* ciResult = [filter outputImage];

    CIContext* context = [CIContext contextWithOptions:nil];
    CGImageRef cgImage = [context createCGImage:ciResult fromRect:[ciResult extent]];
    UIImage* uiResult = [UIImage imageWithCGImage:cgImage scale:1.0 orientation:UIImageOrientationRight];
    CFRelease(cgImage);

    [self performSelectorOnMainThread:@selector(setImageForImageView:) withObject:uiResult waitUntilDone:YES];
    NSLog(@"End process");
}

レイヤーの結果画像を設定します。

- (void) setImageForImageView:(UIImage*)image{
    self.view.layer.contents = image.CGImage;
}

しかし、それは非常に遅れています。オープンソースを見つけました。リアルタイムの画像効果アプリケーションを非常にスムーズに作成します (AVCaptureSession も使用します。では、ここ (私のコードとそのコード) の違いは何ですか?リアルタイムの画像効果処理アプリケーションを作成するにはどうすればよいですか?

これはオープン ソースのリンクです: https://github.com/gobackspaces/DLCImagePickerController#readme

4

1 に答える 1

4

質問で指定したオープン ソース サンプルは、BradLarson による優れたオープン ソース ライブラリGPUImageを使用してリアルタイムの写真とビデオを処理します。このライブラリは、画像処理に GPU ベースのフィルター (OpenGL ES 2.0) を使用します。フレームワークで使用している CPU ベースの画像フィルターよりも比較的高速ですcore image

GPU画像

GPUImage フレームワークは、GPU で高速化されたフィルターやその他の効果を画像、ライブ カメラ ビデオ、およびムービーに適用できる、BSD ライセンスの iOS ライブラリです。Core Image (iOS 5.0 の一部) と比較して、GPUImage は独自のカスタム フィルターを作成でき、iOS 4.0 への展開をサポートし、よりシンプルなインターフェイスを備えています。ただし、現在、顔検出など、Core Image のより高度な機能の一部が欠けています。

画像やライブ ビデオ フレームの処理などの超並列操作の場合、GPU は CPU よりもパフォーマンスが大幅に優れています。iPhone 4 では、単純な画像フィルターを GPU で実行すると、同等の CPU ベースのフィルターよりも 100 倍以上高速になります。

于 2013-05-29T04:34:41.757 に答える