2015-09-05 9 views
8

新しいAndroid顔検出モバイルビジョンAPIを使用している間に、フレーム画像を処理しようとしています。グレースケールバイトバッファイメージからビットマップを作成する方法は?

フレームを取得するためにカスタム検出器を作成し、getBitmap()メソッドを呼び出そうとしましたがnullであるため、フレームのグレースケールデータにアクセスしました。ビットマップを作成する方法や、類似したイメージホルダークラスを作成する方法はありますか?

public class CustomFaceDetector extends Detector<Face> { 
private Detector<Face> mDelegate; 

public CustomFaceDetector(Detector<Face> delegate) { 
    mDelegate = delegate; 
} 

public SparseArray<Face> detect(Frame frame) { 
    ByteBuffer byteBuffer = frame.getGrayscaleImageData(); 
    byte[] bytes = byteBuffer.array(); 
    int w = frame.getMetadata().getWidth(); 
    int h = frame.getMetadata().getHeight(); 
    // Byte array to Bitmap here 
    return mDelegate.detect(frame); 
} 

public boolean isOperational() { 
    return mDelegate.isOperational(); 
} 

public boolean setFocus(int id) { 
    return mDelegate.setFocus(id); 
}} 
+0

フレームは、カメラから直接送られるため、ビットマップデータはありません。カメラの画像フォーマットはNV21です:http://developer.android.com/reference/android/graphics/ImageFormat.html#NV21 – pm0733464

答えて

11

あなたはおそらくすでにこれを整理しますが、場合には、誰かが将来的にこの質問時につまずき、ここで私はそれを解決する方法ですしている:

@ pm0733464が指摘するように、デフォルトの画像形式が来ますandroid.hardware.Cameraのうちの1つはNV21であり、これはCameraSourceによって使用されるものです。

This stackoverflowの答えは答えを提供します。

YuvImage yuvimage=new YuvImage(byteBuffer, ImageFormat.NV21, w, h, null); 
ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
yuvimage.compressToJpeg(new Rect(0, 0, w, h), 100, baos); // Where 100 is the quality of the generated jpeg 
byte[] jpegArray = baos.toByteArray(); 
Bitmap bitmap = BitmapFactory.decodeByteArray(jpegArray, 0, jpegArray.length); 

frame.getGrayscaleImageData()bitmapは、元の画像のグレースケールバージョンになります示唆しているが、これは私の経験では、そうではありません。実際、ビットマップはネイティブにSurfaceHolderに提供されたものと同じです。

+0

これは素晴らしいです。とにかく、私はイメージ全体の代わりに顔を切り取ることができましたか? – Andro

0

検出領域の両側に300pxのボックスを設定するには、いくつかの追加項目を追加するだけです。ところで、メタデータからgetGrayscaleImageData()のフレームの高さと幅を入れないと、奇妙な破損ビットマップが出てきます。

public SparseArray<Barcode> detect(Frame frame) { 
     // *** crop the frame here 
     int boxx = 300; 
     int width = frame.getMetadata().getWidth(); 
     int height = frame.getMetadata().getHeight(); 
     int ay = (width/2) + (boxx/2); 
     int by = (width/2) - (boxx/2); 
     int ax = (height/2) + (boxx/2); 
     int bx = (height/2) - (boxx/2); 

     YuvImage yuvimage=new YuvImage(frame.getGrayscaleImageData().array(), ImageFormat.NV21, frame.getMetadata().getWidth(), frame.getMetadata().getHeight(), null); 
     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     yuvimage.compressToJpeg(new Rect(by, bx, ay, ax), 100, baos); // Where 100 is the quality of the generated jpeg 
     byte[] jpegArray = baos.toByteArray(); 
     Bitmap bitmap = BitmapFactory.decodeByteArray(jpegArray, 0, jpegArray.length); 

     Frame outputFrame = new Frame.Builder().setBitmap(bitmap).build(); 
     return mDelegate.detect(outputFrame); 
    } 

    public boolean isOperational() { 
     return mDelegate.isOperational(); 
    } 

    public boolean setFocus(int id) { 
     return mDelegate.setFocus(id); 
    } 
} 
関連する問題