2011-04-12 16 views
23

Estoy tratando de crear una aplicación de Android que procesará los marcos de la cámara en tiempo real. Para comenzar, solo quiero mostrar una versión en escala de grises de lo que ve la cámara. Logré extraer los valores apropiados de la matriz de bytes en el método onPreviewFrame. A continuación se muestra sólo un fragmento de mi código:Procesamiento de marcos de cámara Android en tiempo real

byte[] pic; 
int pic_size; 
Bitmap picframe; 
public void onPreviewFrame(byte[] frame, Camera c) 
{ 
    pic_size = mCamera.getParameters().getPreviewSize().height * mCamera.getParameters().getPreviewSize().width; 
    pic = new byte[pic_size]; 
    for(int i = 0; i < pic_size; i++) 
    { 
     pic[i] = frame[i]; 
    } 
    picframe = BitmapFactory.decodeByteArray(pic, 0, pic_size); 
} 

Los primeros [width*height] valores de la matriz del marco byte[] son los valores de luminancia (escala de grises). Una vez que los he extraído, ¿cómo los visualizo en la pantalla como una imagen? No es una matriz 2D también, entonces, ¿cómo puedo especificar el ancho y la altura?

Respuesta

10

Puede obtener una amplia guía del OpenCV4Android SDK. Mire en sus ejemplos disponibles, específicamente Tutorial 1 Basic. 0 Android Camera

Pero, como en mi caso, para el procesamiento intensivo de imágenes, esto será más lento que lo aceptable para una aplicación de procesamiento de imágenes en tiempo real. Un buen reemplazo para la conversión de byte array su onPreviewFrame 's a YUVImage:

YuvImage yuvImage = new YuvImage(frame, ImageFormat.NV21, width, height, null);

crear un rectángulo del mismo tamaño que la imagen.

Crear un ByteArrayOutputStream y pasar esta, el rectángulo y el valor de compresión para compressToJpeg():

ByteArrayOutputStream baos = new ByteArrayOutputStream(); yuvimage.compressToJpeg(imageSizeRectangle, 100, baos);

byte [] imageData = baos.toByteArray();

Bitmap previewBitmap = BitmapFactory.decodeByteArray(imageData , 0, imageData .length);

la prestación de estos previewFrames sobre una superficie y las mejores prácticas involucradas es una nueva dimensión. =)

+1

¿Esto sucede para convertir la imagen YUV en un mapa de bits con un JPEG intermediario? Apenas una solución factible en tiempo real – Rekin

+0

Recomiendo encarecidamente que no lo haga. OpenCV en Android agregará complejidad al proyecto y también requerirá las bibliotecas nativas que tienen un tamaño de alrededor de 10 MB. Android tiene todas las facilidades para lograr lo que el OP requiere. OpenCV es una gran biblioteca, pero excesiva para esta situación. – protectedmember

-2

Esta no es una tarea fácil de lograr, con las herramientas/API de Android disponibles actualmente. En general, el procesamiento de imágenes en tiempo real se realiza mejor en el nivel NDK. Para mostrar el blanco y negro, aún puedes hacerlo en Java. La matriz de bytes que contiene los datos de marco está en formato YUV, donde el plano Y es lo primero. Entonces, si obtiene solo el plano Y solo (primer ancho x alto de altura), ya le da el blanco y negro.

Logré esto mediante un extenso trabajo y pruebas. Puede ver la aplicación en google: https://play.google.com/store/apps/details?id=com.nm.camerafx

1

Esta publicación muy antigua ha llamado mi atención ahora.

La API disponible en '11 era mucho más limitada. Hoy se puede usar SurfaceTexture (ver example) para obtener una vista previa de la secuencia de la cámara después de (algunas) manipulaciones.

Cuestiones relacionadas