2015-09-05 18 views
8

Tôi đang cố gắng để có được hình ảnh khung để xử lý trong khi sử dụng Android mới phát hiện khuôn mặt điện thoại di động tầm nhìn api.Làm thế nào để tạo Bitmap từ hình ảnh đệm byte grayscaled?

Vì vậy, tôi đã tạo Custom Detector để nhận Frame và cố gắng gọi phương thức getBitmap() nhưng nó là null vì vậy tôi đã truy cập dữ liệu màu xám của khung. Có cách nào để tạo bitmap từ nó hoặc lớp chủ sở hữu hình ảnh tương tự?

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

Khung không có dữ liệu bitmap vì nó đến trực tiếp từ máy ảnh. Định dạng hình ảnh từ máy ảnh là NV21: http://developer.android.com/reference/android/graphics/ImageFormat.html#NV21 – pm0733464

Trả lời

11

Bạn đã có thể sắp xếp này ra đã có, nhưng trong trường hợp ai đó tình cờ gặp câu hỏi này trong tương lai, đây là cách tôi giải quyết nó:

Như @ pm0733464 chỉ ra, định dạng hình ảnh mặc định sắp tới trong số android.hardware.Camera là NV21 và đó là loại được sử dụng bởi CameraSource.

This stackoverflow câu trả lời cung cấp câu trả lời:

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); 

Mặc dù frame.getGrayscaleImageData() gợi ý bitmap sẽ là một phiên bản màu xám của ảnh gốc, đây không phải là trường hợp, trong kinh nghiệm của tôi. Trên thực tế, bitmap giống hệt bitmap được cung cấp cho số SurfaceHolder.

+0

Điều này hoạt động tốt. Dù sao tôi chỉ có thể cắt mặt thay vì toàn bộ hình ảnh? – Andro

0

Chỉ cần thêm một vài tính năng bổ sung để đặt hộp 300px ở mỗi bên cho khu vực phát hiện. Bằng cách này nếu bạn don'y đặt trong chiều cao khung hình và chiều rộng trong getGrayscaleImageData() từ siêu dữ liệu bạn nhận được bitmap hỏng bị hỏng ra ngoài.

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); 
    } 
} 
Các vấn đề liên quan