Extrahieren Sie Schwarz-Weiß-Bild aus der NV21-Format der Android-Kamera

Ich habe einige google-ing herum und konnte nicht genug Informationen über dieses Format finden. Es ist das Standardformat für die Kameravorschau. Kann jemand vorschlagen, gute Informationsquellen darüber und wie man Daten aus einem Foto / Vorschaubild mit diesem Format extrahiert? Um genauer zu sein, brauche ich das Schwarz-Weiß-Bild extrahiert.

EDIT: Scheint so, dass das Format auch YCbCr 420 Semi Planar heißt

  • Android - neueste Open-Source-3D-Bibliotheken für Android
  • Smack 4.1 Re-Verbindung Problem
  • Google Analytics v4 - Daten, die nicht im Dashboard angezeigt werden
  • Installieren Sie SD-Karte vs Telefonspeicher? Und warum unterscheidet sich die Größe der App?
  • Wie kann ich benutzerdefinierte Schaltflächen in das Layout eines AlertDialogs einfügen?
  • Wie man dieses JSON Array in Android analysiert
  • Ist es möglich, einen Tomcat-Server und einige Webanwendungen auf einem Android-Gerät auszuführen? (Dh eine Tablette)
  • So verwenden Sie die setDuration () - Methode in SnackBar (Android Design Support Library)
  • VLC RTSP Live Stream auf Android
  • Android java.lang.ArrayIndexOutOfBoundsException: length = 10; Index = 10
  • Map.clear () vs neue Karte: Welches wird besser sein?
  • BlueZ vs Bluedroid bluetooth Stapel
  • 6 Solutions collect form web for “Extrahieren Sie Schwarz-Weiß-Bild aus der NV21-Format der Android-Kamera”

    Ich habe den folgenden Code entwickelt, um den NV21 in RGB umzuwandeln, und es funktioniert.

     /** * Converts YUV420 NV21 to RGB8888 * * @param data byte array on YUV420 NV21 format. * @param width pixels width * @param height pixels height * @return a RGB8888 pixels int array. Where each int is a pixels ARGB. */ public static int[] convertYUV420_NV21toRGB8888(byte [] data, int width, int height) { int size = width*height; int offset = size; int[] pixels = new int[size]; int u, v, y1, y2, y3, y4; // i percorre os Y and the final pixels // k percorre os pixles U e V for(int i=0, k=0; i < size; i+=2, k+=2) { y1 = data[i ]&0xff; y2 = data[i+1]&0xff; y3 = data[width+i ]&0xff; y4 = data[width+i+1]&0xff; u = data[offset+k ]&0xff; v = data[offset+k+1]&0xff; u = u-128; v = v-128; pixels[i ] = convertYUVtoRGB(y1, u, v); pixels[i+1] = convertYUVtoRGB(y2, u, v); pixels[width+i ] = convertYUVtoRGB(y3, u, v); pixels[width+i+1] = convertYUVtoRGB(y4, u, v); if (i!=0 && (i+2)%width==0) i+=width; } return pixels; } private static int convertYUVtoRGB(int y, int u, int v) { int r,g,b; r = y + (int)(1.402f*v); g = y - (int)(0.344f*u +0.714f*v); b = y + (int)(1.772f*u); r = r>255? 255 : r<0 ? 0 : r; g = g>255? 255 : g<0 ? 0 : g; b = b>255? 255 : b<0 ? 0 : b; return 0xff000000 | (b<<16) | (g<<8) | r; } 

    Dieses Bild hilft zu verstehen. YUV420 NV21

    Wenn du nur Graustufenbild willst, ist es einfacher. Du kannst alle U- und V-Infos verwerfen und nimm nur die Y-Info. Der Code könnte so sein:

     /** * Converts YUV420 NV21 to Y888 (RGB8888). The grayscale image still holds 3 bytes on the pixel. * * @param pixels output array with the converted array o grayscale pixels * @param data byte array on YUV420 NV21 format. * @param width pixels width * @param height pixels height */ public static void applyGrayScale(int [] pixels, byte [] data, int width, int height) { int p; int size = width*height; for(int i = 0; i < size; i++) { p = data[i] & 0xFF; pixels[i] = 0xff000000 | p<<16 | p<<8 | p; } } 

    So erstellen Sie Ihre Bitmap nur:

     Bitmap bm = Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888); 

    Wo Pixel dein int [] Array ist.

    NV21 ist grundsätzlich YUV420 aber anstelle von planarem Format, wobei Y, U und V unabhängige Ebenen haben, NV21 hat 1 Ebene für Luma und 2. Ebene für Chroma. Das Format sieht aus wie

    JANIJJJJJJJJJJJJJJJJINYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY . . .

    VUVUVUVUVUVUVUVUVUVUVUVUVUVUVU VUVUVUVUVUVUVUVUVUVUVUVUVUVUVU. . . . .

    Ich hatte auch viel Kopfschmerzen wegen dieses Vorschau-Formats.

    Das Beste, was ich finden konnte, sind:

    http://www.fourcc.org/yuv.php#NV21

    http://v4l2spec.bytesex.org/spec/r5470.htm

    Es scheint, dass die Y-Komponente die erste Breite * Höhe Bytes in der Array Sie erhalten.

    Weitere Informationen:

    http://msdn.microsoft.com/en-us/library/ms867704.aspx#yuvformats_yuvsampling

    http://msdn.microsoft.com/en-us/library/ff538197(v=vs.85).aspx

    Hoffe das hilft.

    Die Daten befinden sich im Format YUV420.
    Wenn Sie sich nur für den monochromen Kanal interessieren, also "black and white", dann ist dies die erste width x height Höhenbytes des Datenpuffers, die Sie bereits haben.
    Der Y Kanal ist die erste Bildebene. Es ist genau der Grau / Intensität / Leuchtkraft etc. Kanal.

    Hier ist der Code, um einfach die Graustufen-Bilddaten zu extrahieren:

     private int[] decodeGreyscale(byte[] nv21, int width, int height) { int pixelCount = width * height; int[] out = new int[pixelCount]; for (int i = 0; i < pixelCount; ++i) { int luminance = nv21[i] & 0xFF; out[i] = Color.argb(0xFF, luminance, luminance, luminance); } return out; } 

    Wenn Sie nur eine Graustufen-Kamera-Vorschau benötigen, können Sie ein sehr einfaches Renderscript verwenden:

     # pragma version(1) # pragma rs java_package_name(com.example.name) # pragma rs_fp_relaxed rs_allocation gIn; // Allocation filled with camera preview data (byte[]) int previewwidth; // camera preview width (int) // the parallel executed kernel void root(uchar4 *v_out, uint32_t x,uint32_t y){ uchar c = rsGetElementAt_uchar(gIn,x+y*previewwidth); *v_out = (uchar4){c,c,c,255}; } 

    Hinweis: Dies ist nicht schneller als ScriptIntrinsicYuvToRGB (und eine folgende ScriptIntrinsicColorMatrix, um das RGBA-> Grau zu machen), aber es läuft mit API 11+ (wo die Intrinsics Api 17+ benötigt).

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.