如何创建实时图像效果处理应用程序iOS

如何创建实时图像效果处理应用程序iOS,ios,image-processing,Ios,Image Processing,我使用AVCaptureSession从iPhone的摄像头接收图像。它在委托函数中返回图像。在此函数中,我创建图像并调用其他线程来处理此图像: - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection{ // static b

我使用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。那么,这里有什么区别(我的代码和他们的代码)?如何创建实时图像效果处理应用程序?


这是开源链接:

您在问题中指定的开源示例,使用BradLarson的优秀开源库进行实时照片和视频处理。该库使用基于GPU的过滤器(OpenGL ES 2.0)用于图像处理。相对而言,它比
核心图像
框架使用的基于CPU的图像文件管理器更快

GPUImage框架是一个BSD许可的iOS库,允许您将GPU加速过滤器和其他效果应用于图像、实时摄像机视频和电影。与核心图像(iOS 5.0的一部分)相比,GPUImage允许您编写自己的自定义过滤器,支持部署到iOS 4.0,并且具有更简单的界面。但是,它目前缺少核心图像的一些更高级功能,例如面部检测

对于处理图像或实时视频帧等大规模并行操作,GPU比CPU具有一些显著的性能优势。在iPhone 4上,一个简单的图像过滤器在GPU上的执行速度比同等的基于CPU的过滤器快100多倍


您在问题中指定的开源示例使用BradLarson的优秀开源库进行实时照片和视频处理。该库使用基于GPU的过滤器(OpenGL ES 2.0)用于图像处理。相对而言,它比
核心图像
框架使用的基于CPU的图像文件管理器更快

GPUImage框架是一个BSD许可的iOS库,允许您将GPU加速过滤器和其他效果应用于图像、实时摄像机视频和电影。与核心图像(iOS 5.0的一部分)相比,GPUImage允许您编写自己的自定义过滤器,支持部署到iOS 4.0,并且具有更简单的界面。但是,它目前缺少核心图像的一些更高级功能,例如面部检测

对于处理图像或实时视频帧等大规模并行操作,GPU比CPU具有一些显著的性能优势。在iPhone 4上,一个简单的图像过滤器在GPU上的执行速度比同等的基于CPU的过滤器快100多倍


我也尝试使用OpenGL,但它仍然滞后。我想原因是我必须从摄像头到字节数组读取UIImage。我可以从captureOutput delegate获取纹理吗?@huync-你可以看看我在GPUImageVideoCamera中上传视频的代码,看看我是如何做到这一点的。基本上,我可以直接从CV中上传字节PixelBufferRef或最好使用iOS 5.0对纹理缓存的支持来快速上传到OpenGL ES。在上面的代码中,您正在将CVPixelBufferRed转换为UIImage,这是一个非常缓慢的过程,不需要将原始图像字节上传到核心图像。同样,您可以查看我的BenchmarkSuite示例应用程序,了解您是如何实现的“我想在使用核心图像时这样做。GPUImage速度更快。@布拉德拉尔森:非常感谢。你的项目非常伟大、庞大而且有用。我以前用过它。我会看看你的代码。我也尝试使用OpenGL,但它仍然滞后。我想原因是我必须从摄影机到字节数组读取UIImage。我能从captureOutp获取纹理吗?”ut delegate?@huync-你可以看看我在GPUImageVideoCamera中上传视频的代码,看看我是如何做到这一点的。基本上,我要么直接从CVPixelBufferRef中上传字节,要么最好使用iOS 5.0对纹理缓存的支持来快速上传到OpenGL ES。在上面的代码中,你正在转换你的CVPixelBufferRed到UIImage,这是一个非常缓慢的过程,不需要将原始图像字节上载到Core image。同样,您可以查看我的BenchmarkSuite示例应用程序,了解如何使用Core image实现这一点。不过,GPUIImage速度更快。@BradLarson:非常感谢。您的项目非常伟大、庞大且有用t、 我以前用过。我会看看你的代码。