Domanda

Sto cercando di fare un po 'di elaborazione delle immagini su iPhone. Sto utilizzando http://developer.apple.com/library/ ios / # qa / qa2010 / qa1702.html di catturare i fotogrammi della telecamera.

Il mio problema è che quando sto cercando di accedere al buffer catturato, la fotocamera FPS scende da 30 a circa 20. Qualcuno sa come posso risolvere il problema?

Io uso la qualità di acquisizione più basso che ho trovato (AVCaptureSessionPresetLow = 192x144) in formato kCVPixelFormatType_32BGRA. Se qualcuno conosce una qualità inferiore che potrei usare, io sono disposto a provarlo.

Quando faccio lo stesso accesso immagine su altre piattaforme, come Symbian, funziona OK.

Ecco il mio codice:

#pragma mark -
#pragma mark AVCaptureSession delegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput 
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
    fromConnection:(AVCaptureConnection *)connection 
{ 
 /*We create an autorelease pool because as we are not in the main_queue our code is
  not executed in the main thread. So we have to create an autorelease pool for the thread we are in*/
 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
 //Lock the image buffer
    if (CVPixelBufferLockBaseAddress(imageBuffer, 0) == kCVReturnSuccess)
    {  

  // calculate FPS and display it using main thread
  [self performSelectorOnMainThread:@selector(updateFps:) withObject: (id) nil waitUntilDone:NO];


  UInt8 *base = (UInt8 *)CVPixelBufferGetBaseAddress(imageBuffer); //image buffer start address

  size_t width  = CVPixelBufferGetWidth(imageBuffer); 
  size_t height = CVPixelBufferGetHeight(imageBuffer);

  int size = (height*width);
  UInt8* pRGBtmp = m_pRGBimage;

        /*
        Here is the problem; m_pRGBimage is RGB image I want to process.
        In the 'for' loop I convert the image from BGRA to RGB. As a resault, the FPS drops to 20.
        */ 
  for (int i=0;i<size;i++)
  {   
    pRGBtmp[0] = base[2];
    pRGBtmp[1] = base[1];
    pRGBtmp[2] = base[0];
    base = base+4;
    pRGBtmp = pRGBtmp+3;     
  }


  // Display received action
  [self performSelectorOnMainThread:@selector(displayAction:) withObject: (id) nil waitUntilDone:NO];
  //[self displayAction:&eyePlayOutput];
  //saveFrame( imageBuffer );

  //unlock the  image buffer
  CVPixelBufferUnlockBaseAddress(imageBuffer,0);

 }


 [pool drain];
} 

Come follow-on per le risposte, ho bisogno di elaborare l'immagine in tempo reale, esso viene visualizzato.

Ho notato che quando uso AVCaptureSessionPresetHigh, il più semplice, cosa che faccio, come:

 for (int i=0;i<size;i++)
    x = base[0];

fa sì che il framerate a scendere a 4-5 FPS. Credo che la sua causa di un'immagine in quella dimensione non è memorizzato nella cache.

Fondamentalmente ho bisogno di un'immagine 96x48. c'è un modo semplice per rimpicciolire l'immagine di uscita telecamera, un modo che l'accelerazione usi hardware, così ho potuto lavorare con il piccolo?

È stato utile?

Soluzione

Tutto ciò che itera su ogni pixel in un'immagine sarà abbastanza lento su tutti, ma i più veloci dispositivi iOS. Ad esempio, l'iterazione I parametri di riferimento su ogni pixel in un fotogramma video 640 x 480 (307.200 pixel) con un test semplice colore per pixel e ha scoperto che questo solo funziona a circa 4 FPS su un iPhone 4.

Sei nella lavorazione di 27.648 pixel nel tuo caso, che dovrebbe correre abbastanza velocemente per colpire 30 FPS su un iPhone 4, ma questo è un processore molto più veloce di quello che era nel modello originale di iPhone e iPhone 3G. L'iPhone 3G sarà probabilmente ancora lottare con questo carico di elaborazione. Inoltre non dire quanto velocemente il processore era nei dispositivi Symbian.

suggerirei rielaborare l'algoritmo di elaborazione al fine di evitare la conversione dello spazio colore. Non ci dovrebbe essere bisogno di riordinare le componenti di colore al fine di elaborarli.

Inoltre, si può elaborare in modo selettivo soltanto alcuni pixel campionando a determinati intervalli all'interno delle righe e colonne dell'immagine.

Infine, se si prendono di mira i dispositivi iOS più recenti che hanno il supporto per OpenGL ES 2.0 (iPhone 3G S e successivi), si potrebbe desiderare di guardare con uno shader frammento GLSL per elaborare il fotogramma video interamente sulla GPU. Descrivo il processo qui , insieme al codice di esempio per in tempo reale il monitoraggio oggetto basata sul colore. La GPU in grado di gestire questo tipo di lavorazione 14 -. 28 volte più veloce rispetto alla CPU, ai miei punti di riferimento

Altri suggerimenti

responsabilità: questo risposta è un GUESS:)

Si sta facendo un bel po 'di lavoro, mentre il buffer è bloccato; è questo in mano il filo che sta catturando l'immagine della telecamera?

Si potrebbe copiare i dati dal buffer mentre si lavora su di esso in modo da poter sbloccare al più presto vale a dire una cosa del genere

if (CVPixelBufferLockBaseAddress(imageBuffer, 0) == kCVReturnSuccess) {
    // Get the base address and size of the buffer
    UInt8 *buffer_base = (UInt8 *)CVPixelBufferGetBaseAddress(imageBuffer); //image buffer start address
    size_t width  = CVPixelBufferGetWidth(imageBuffer); 
    size_t height = CVPixelBufferGetHeight(imageBuffer);

    // Copy it's contents out
    Uint8 *base = malloc(width * height * 4);
    memcpy(base, buffer_base, size);

    // Unlock the buffer
    CVPixelBufferUnlockBaseAddress(imageBuffer,0);

    // base now points to a copy of the buffers' data - do what you want to it . . .
    ...

    // remember to free base once you're done ;)
    free(base);

Se è il blocco che sta alzando la cattura, allora questo dovrebbe aiutare.

NB Si potrebbe accelerare l'operazione se si conoscono tutti i buffer sarà lo stesso formato potete malloc solo chiamata una volta per ottenere la memoria e poi basta riutilizzarlo ogni volta e libero solo quando hai finito di elaborazione di tutti i buffer.


Se non è questo il problema si potrebbe provare a ridurre la priorità di questa discussione

[NSThread setThreadPriority:0.25];

copia il contenuto del frame telecamera in un buffer dedicato e operano su di esso da lì. Questo si traduce in un enorme miglioramento della velocità nella mia esperienza. La mia ipotesi migliore è che l'area di memoria in cui si trova il telaio fotocamera dispone di protezioni speciali che rendono la lettura / scrittura accessi lenta.

Controlla l'indirizzo di memoria dei dati telaio della macchina fotografica. Sul mio dispositivo buffer della fotocamera è a 0x63ac000. Ciò non significa niente per me, se non che gli altri oggetti heap sono gli indirizzi più vicini alla 0x1300000. Il suggerimento di blocco non ha risolto il mio rallentamento, ma il fatto memcpy.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top