2015-09-05 6 views
8

मैं नए एंड्रॉइड चेहरे का पता लगाने मोबाइल दृष्टि एपीआई का उपयोग करते समय प्रक्रिया करने के लिए फ्रेम छवि प्राप्त करने की कोशिश कर रहा हूं।ग्रेस्केल बाइट बफर छवि से बिटमैप कैसे बनाएं?

इसलिए मैंने फ्रेम प्राप्त करने के लिए कस्टम डिटेक्टर बनाया है और 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

फ्रेम में बिटमैप डेटा नहीं है क्योंकि यह सीधे कैमरे से आता है। कैमरे से छवि प्रारूप एनवी 21 है: http://developer.android.com/reference/android/graphics/ImageFormat.html#NV21 – pm0733464

उत्तर

11

आप शायद इस पहले से ही का हल दिया है, लेकिन इस मामले में किसी को भविष्य में इस सवाल पर ठोकर, यहाँ मैं इसे कैसे हल किया है:

के रूप में @ pm0733464 बताते हैं, डिफ़ॉल्ट छवि प्रारूप आ रहा android.hardware.Camera में से एनवी 21 है, और यह CameraSource द्वारा उपयोग किया जाता है।

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 मूल चित्र की ग्रेस्केल संस्करण हो जाएगा, यह, ऐसा नहीं है मेरे अनुभव में:

This stackoverflow जवाब इस सवाल का जवाब देता है। वास्तव में, बिटमैप 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); 
    } 
} 
संबंधित मुद्दे