2013-08-26 23 views
10

Sto progettando un'applicazione che ha una pipeline di elaborazione OpenGL (raccolta di shader) e richiede simultaneamente all'utente finale di vedere l'anteprima della fotocamera non elaborata .Anteprima ed elaborazione simultanee della fotocamera

Per esempio, si supponga di voler mostrare all'utente l'anteprima della fotocamera e allo stesso tempo contare il numero di oggetti rossi nelle scene che si ricevono dalla fotocamera, ma tutti gli ombreggiatori che si utilizzano per contare gli oggetti come come filtro della tonalità, ecc. non dovrebbe essere visto dall'utente.

Come dovrei fare per configurarlo correttamente?

So che posso impostare un'anteprima della telecamera e quindi sul callback ricevere i dati della cornice della fotocamera in formato YUV, quindi riversarlo in una trama OpenGL ed elaborare il fotogramma in quel modo, tuttavia, che ha problemi di prestazioni ad esso associati. Devo arrotondare i dati dall'hardware della videocamera alla VM, quindi restituirlo alla memoria della GPU. Sto usando SurfaceTexture per ottenere i dati dalla fotocamera direttamente in formato comprensibile OpenGL e passarli ai miei shader per risolvere questo problema.

ho pensato che sarei in grado di dimostrare che lo stesso non trasformati SurfaceTexture per l'utente finale, ma TextureView non avere un costruttore o un setter dove posso passare la SurfaceTexture voglio che il rendering. Crea sempre il suo.

Questa è una panoramica della mia configurazione corrente:

  • GLRenderThread: questa classe si estende da Thread, messe a punto contesto OpenGL, esposizione, ecc e utilizza un SurfaceTexture come la superficie (3 ° parametro di eglCreateWindowSurface).
  • GLFilterChain: una raccolta di shader che eseguono il rilevamento sulla trama dell'input.
  • fotocamera: Usa un SurfaceTexture separata che viene usato come input di GLFilterChain e afferra anteprima della fotocamera
  • Finalmente un TextureView che visualizza SurfaceTexture del GLRenderThread

Ovviamente, con questa configurazione, sto mostrando il frame elaborati all'utente che non è quello che voglio. Inoltre, l'elaborazione dei frame non è in tempo reale. Fondamentalmente, eseguo l'input dalla videocamera attraverso la catena una volta e una volta che tutti i filtri sono terminati, chiamo updateTexImage per prendere il fotogramma successivo dalla fotocamera. La mia elaborazione è di circa 10 fotogrammi al secondo su Nexus 4.

Penso che probabilmente ho bisogno di usare 2 contesti GL, uno per l'anteprima in tempo reale e uno per l'elaborazione, ma non ne sono certo. Spero che qualcuno possa spingermi nella giusta direzione.

+0

http://stackoverflow.com/questions/12519235/modifying-camera-output-using-surfacetexture-and-opengl –

risposta

0

puoi caricare un po 'del codice che stai utilizzando?

potresti essere in grado di chiamare glDrawArrays su una texture creata e vincolata alla vista di superficie che stai utilizzando per visualizzare inizialmente l'anteprima, quindi svuotarla e associare una trama separata con l'altra trama per eseguire l'analisi? qualcosa come

GLES20.glUseProgram(simpleProgram); 
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textures[0]); 
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); 

GLES20.glUseProgram(crazyProgram); 
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textures[1]); 
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); 

dove anteprima surfacetexture della fotocamera è destinata a texture [0] e poi una surfacetexture separata creato per la texture [1]

forse?

+0

Il mio codice comprende molte classi, ma cercherò di aggiungere un sommario alla domanda. Quindi, per ricapitolare la tua idea: simpleProgram imposta semplicemente gl_FragColor sul valore del pixel di input. crazyProgram esegue l'elaborazione effettiva. Non userò affatto TextureView e useremo GLSurfaceView per mostrare l'anteprima all'utente. Come copio texturres [0] in texture [1] e come terrò l'anteprima della fotocamera in tempo reale? Sulla base della mia comprensione, prima di usare crazyProgram, devo associare un framebuffer non predefinito, il che significa che la prossima anteprima della fotocamera deve attendere fino a quando crazyProgram non ha eseguito tutta la sua elaborazione. – Ameen

0

A meno che l'elaborazione sia più lenta del tempo reale, la risposta è semplice: basta mantenere intatta la trama della fotocamera originale, calcolare l'immagine elaborata su una trama diversa e visualizzarla all'utente, affiancata in una sola GLview. Mantieni un singolo thread, poiché l'elaborazione avviene comunque sulla GPU. I thread multipli complicano solo le cose qui.

Il numero di passaggi di elaborazione non ha molta importanza, in quanto vi può essere un numero arbitrario di trame intermedie (vedi anche ping-pong) che non vengono mai visualizzate all'utente - nessuno e nessuno ti sta costringendo.

La nozione di tempo reale è probabilmente confusa qui. Basti pensare a una cornice come a un'istantanea del tempo indivisibile. In tal modo, ignorerai il ritardo che l'immagine impiega a passare dalla fotocamera allo schermo, ma se puoi mantenerla a frequenze di fotogrammi interattive (come almeno 20 fotogrammi al secondo), allora questo può essere ignorato.

D'altra parte, se l'elaborazione è molto più lenta, è necessario scegliere tra l'introduzione di un ritardo nell'alimentazione della telecamera ed elaborare solo ogni fotogramma N °, o alternativamente visualizzare ogni fotogramma della telecamera in tempo reale e lasciare che il prossimo fotogramma elaborato in ritardo. Per fare ciò, probabilmente occorrono due distinti contesti di rendering per abilitare l'elaborazione asincrona, che potrebbe essere potenzialmente difficile da fare su Android (o forse semplicemente come creare un secondo GLView, dal momento che si può vivere senza condivisione dei dati tra i contesti).

Problemi correlati