gru*_*htr 12 iphone camera avfoundation ios
我正在尝试编写一个iPhone应用程序,它将进行一些实时的相机图像处理.我使用AVFoundation文档中提供的示例作为起点:设置捕获会话,从示例缓冲区数据创建UIImage,然后在一个点上绘制图像-setNeedsDisplay,我在主线程上调用.
这是有效的,但它相当慢(每帧50毫秒,在-drawRect:调用之间测量,对于192 x 144预设)我已经看到App Store上的应用程序比这更快.
我大约一半的时间都花在了-setNeedsDisplay.
如何加快图像处理速度?
Bra*_*son 21
史蒂夫指出,在我的回答中,我鼓励人们在从iPhone的相机处理图像并将图像渲染到屏幕时,查看OpenGL ES以获得最佳性能.原因是使用Quartz不断将UIImage更新到屏幕上是将原始像素数据发送到显示器的一种相当慢的方法.
如果可能的话,我建议您查看OpenGL ES来进行实际处理,因为GPU的调整方式非常适合这类工作.如果您需要保持OpenGL ES 1.1的兼容性,那么您的处理选项比使用2.0的可编程着色器更受限制,但您仍然可以进行一些基本的图像调整.
即使您使用CPU上的原始数据进行所有图像处理,通过对图像数据使用OpenGL ES纹理,每帧更新一次,您仍然会更好.只需切换到渲染路线,您就会看到性能的提升.
(更新:2012年2月18日)正如我在上述链接答案的更新中描述的那样,我使用新的开源GPUImage框架使这个过程变得更加容易.它可以为您处理所有OpenGL ES交互,因此您可以专注于在传入视频上应用过滤器和其他效果.它使用CPU绑定例程和手动显示更新比使用此处理快5-70倍.
将sessionPresent的捕获会话设置为AVCaptureSessionPresetLow,如下面的示例代码所示,这将提高处理速度,但缓冲区中的图像质量较差.
- (void)initCapture {
AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput
deviceInputWithDevice:[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]
error:nil];
AVCaptureVideoDataOutput *captureOutput = [[AVCaptureVideoDataOutput alloc] init] ;
captureOutput.alwaysDiscardsLateVideoFrames = YES;
captureOutput.minFrameDuration = CMTimeMake(1, 25);
dispatch_queue_t queue;
queue = dispatch_queue_create("cameraQueue", NULL);
[captureOutput setSampleBufferDelegate:self queue:queue];
dispatch_release(queue);
NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey;
NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA];
NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:value forKey:key];
[captureOutput setVideoSettings:videoSettings];
self.captureSession = [[AVCaptureSession alloc] init] ;
[self.captureSession addInput:captureInput];
[self.captureSession addOutput:captureOutput];
self.captureSession.sessionPreset=AVCaptureSessionPresetLow;
/*sessionPresent choose appropriate value to get desired speed*/
if (!self.prevLayer) {
self.prevLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
}
self.prevLayer.frame = self.view.bounds;
self.prevLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer addSublayer: self.prevLayer];
}
| 归档时间: |
|
| 查看次数: |
15250 次 |
| 最近记录: |