2015-03-12 1 views
6

J'essaie de faire du traitement d'image en temps réel avec un iPhone 6 à 240fps. Le problème est que lorsque je capture une vidéo à cette vitesse, je ne peux pas traiter l'image assez rapidement car j'ai besoin d'échantillonner chaque pixel pour obtenir une moyenne. Réduire la résolution de l'image permettrait de résoudre facilement ce problème, mais je ne suis pas en mesure de comprendre comment faire cela. Les AVCaptureDeviceFormat disponibles ont des options avec 192x144 px, mais à 30fps. Toutes les options 240fps ont toutes des dimensions plus grandes. Voici comment j'échantillonne les données:Comment obtenir 240fps sur l'iPhone 6 avec une basse résolution

- (void)startDetection 
{ 
    const int FRAMES_PER_SECOND = 240; 
    self.session = [[AVCaptureSession alloc] init]; 
    self.session.sessionPreset = AVCaptureSessionPresetLow; 

    // Retrieve the back camera 
    NSArray *devices = [AVCaptureDevice devices]; 
    AVCaptureDevice *captureDevice; 
    for (AVCaptureDevice *device in devices) 
    { 
     if ([device hasMediaType:AVMediaTypeVideo]) 
     { 
      if (device.position == AVCaptureDevicePositionBack) 
      { 
       captureDevice = device; 
       break; 
      } 
     } 
    } 

    NSError *error; 
    AVCaptureDeviceInput *input = [[AVCaptureDeviceInput alloc] initWithDevice:captureDevice error:&error]; 
    [self.session addInput:input]; 

    if (error) 
    { 
     NSLog(@"%@", error); 
    } 

    // Find the max frame rate we can get from the given device 
    AVCaptureDeviceFormat *currentFormat; 
    for (AVCaptureDeviceFormat *format in captureDevice.formats) 
    { 
     NSArray *ranges = format.videoSupportedFrameRateRanges; 
     AVFrameRateRange *frameRates = ranges[0]; 

     // Find the lowest resolution format at the frame rate we want. 
     if (frameRates.maxFrameRate == FRAMES_PER_SECOND && (!currentFormat || (CMVideoFormatDescriptionGetDimensions(format.formatDescription).width < CMVideoFormatDescriptionGetDimensions(currentFormat.formatDescription).width && CMVideoFormatDescriptionGetDimensions(format.formatDescription).height < CMVideoFormatDescriptionGetDimensions(currentFormat.formatDescription).height))) 
     { 
      currentFormat = format; 
     } 
    } 

    // Tell the device to use the max frame rate. 
    [captureDevice lockForConfiguration:nil]; 
    captureDevice.torchMode=AVCaptureTorchModeOn; 
    captureDevice.activeFormat = currentFormat; 
    captureDevice.activeVideoMinFrameDuration = CMTimeMake(1, FRAMES_PER_SECOND); 
    captureDevice.activeVideoMaxFrameDuration = CMTimeMake(1, FRAMES_PER_SECOND); 
    [captureDevice setVideoZoomFactor:4]; 
    [captureDevice unlockForConfiguration]; 

    // Set the output 
    AVCaptureVideoDataOutput* videoOutput = [[AVCaptureVideoDataOutput alloc] init]; 

    // create a queue to run the capture on 
    dispatch_queue_t captureQueue=dispatch_queue_create("catpureQueue", NULL); 

    // setup our delegate 
    [videoOutput setSampleBufferDelegate:self queue:captureQueue]; 

    // configure the pixel format 
    videoOutput.videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA], (id)kCVPixelBufferPixelFormatTypeKey, 
           nil]; 
    videoOutput.alwaysDiscardsLateVideoFrames = NO; 
    [self.session addOutput:videoOutput]; 

    // Start the video session 
    [self.session startRunning]; 
} 
+2

Je ne pense pas que vous pouvez forcer 240fps sur un périphérique, c'est le maximum, et simultanément les images sont traitées, si le traitement est lourd, l'image par seconde va tomber, je vous suggère d'utiliser la fonction 'imageFromSampleBuffer' de l'échantillon d'Apple code pour obtenir un UIImage, qui est redimensionné plus tard avant le traitement, cela devrait accélérer le traitement de l'image. – gabbler

+0

Une idée intéressante. Je n'avais pas pensé à redimensionner l'image après qu'elle avait déjà été récupérée, mais avant de faire mon analyse. Je vais essayer et voir quel impact sur les performances cela a eu. Espérons que le redimensionnement de l'image serait le fonctionnement de la carte graphique, donc le processeur ne sera pas beaucoup affecté. – lehn0058

+1

C'est ce que je fais, je redimensionne avec CG quand je récupère du buffer de pixel, car je veux 640x480 @ 60fps et Apple ne le supporte pas. Curieux, pourquoi voulez-vous faire du traitement d'image à cette vitesse inhumaine? – aledalgrande

Répondre

0

Essayez la bibliothèque GPUImage. Chaque filtre a la méthode forceProcessingAtSize:. Après le redimensionnement forcé sur GPU, vous pouvez récupérer des données avec GPUImageRawDataOutput.

J'ai obtenu 60fps avec l'image de processus sur CPU avec cette méthode.