2012-03-15 21 views
9

Tengo una aplicación que toma una vista previa de la cámara, realiza una función básica de procesamiento de imágenes en cada fotograma (por ejemplo, detección de bordes, cambio de color, deformación de imagen, etc.) y muestra el fotograma modificado en la pantalla "tiempo real". Similar a la aplicación "Paper Camera" en Android Market.Android: procesamiento de imágenes en tiempo real

Un resumen de mi enfoque:

1: Crear dos Vistas superpuestas en un FrameLayout:

Un SurfaceView para pasar a Camera.setPreviewDisplay(). (Pasar nulo evitaría que la vista previa de la cámara comenzara en algunos dispositivos: ¿OpenCv solía hacer esto antes de Android 4.0?).

Una clase llamada "LiveView" que extiende View e implementa Camera.PreviewCallBack. Esta vista recibe marcos de la cámara y muestra el marco después de la modificación (por ejemplo, detección de bordes). Esta vista se encuentra en la parte superior de SurfaceView.

2: Me llamo Camera.setPreviewCallbackWithBuffer(), por lo que las tramas se envían a mi LiveView

3: En el onPreviewFrame() del LiveView, tomo el fotograma capturado (byte []) , convertir de YUV a RGB y realizar funciones de procesamiento de imágenes, y llamar a postInvalidate() (el procesamiento de conversión y la imagen YUV2RGB se realiza en código nativo)

4: en el método OnDraw() de LiveView, creo una mapa de bits de la trama RGB modificada (byte []) y dibuje el mapa de bits en lienzo.

Esto funciona (entre 5 fps y 10 fps en varios dispositivos), pero me gustaría escuchar cómo otros han abordado este problema y cómo podría mejorarse. En particular:

  • ¿Obtendré algún rendimiento extendiendo GLSurfaceView en lugar de View para crear la clase LiveView?
  • Suena muy ineficiente tener dos superficies actualizadas para cada cuadro. ¿Hay una alternativa?
  • Para hacer esto de manera más eficiente, ¿debería acceder a la cámara a nivel nativo? - Creo que OpenCV tiene este enfoque?

Muchas Gracias

Respuesta

4

También he hecho algo como esto. Lo que hago es extender la vista de la cámara. No creo que la vista de la cámara se actualice en cada cuadro, sino que se recupere. Y solo la Vista que ha cambiado debería actualizarse. OpenCv do hace un mejor trabajo que la cámara nativa. Después de importar org.opencv.highgui.VideoCapture, se puede acceder directamente a la cámara usando:

VideoCapture camera; 
camera.retrieve(mGrayMat, Highgui.CV_CAP_ANDROID_GREY_FRAME); 

para convertir mGrayMat a mRgbaMat: (org.opencv.imgproc.Imgproc)

Imgproc.cvtColor(mGrayMat, mRgbaMat, Imgproc.COLOR_GRAY2BGRA, 4); 
Cuestiones relacionadas