2015-09-05 135 views
8

我想獲得幀圖像,同時採用最新的Android臉部偵測移動視覺API來處理。如何從灰度字節緩衝區圖像創建位圖?

所以我創建的自定義探測器獲得幀,並試圖調用getBitmap()方法,但它爲空,所以我訪問幀的灰度級數據。有沒有辦法從它創建位圖或類似的圖像持有人類?

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是NV21,那就是通過CameraSource使用的一個。

This計算器的答案提供了答案:

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

在幾個羣衆演員只是增加了設定的300像素的盒子上的每一側檢測區域。由()從元數據,如果你don'y放在幀的高度和寬度在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); 
    } 
}