2017-06-20 94 views
0

很多關於camera2 api和RAW圖像格式的問題,但在網上搜索我還沒有找到答案(這就是爲什麼我在這裏btw)。Camera2 api Imageformat.yuv_420_888旋轉後的圖像結果

我正在嘗試使用ImageReader使用ImageReader以及setRepeatingRequest與前置攝像頭對攝像頭拍攝的幀進行一些實時圖像處理。如上所述,在一些先前的文章建議,我獲取圖像中,以便一個RAW格式(具體Imageformat.yuv_420_888)爲具有大約30fps的幀速率:

imageReader = ImageReader.newInstance(width, height, ImageFormat.YUV_420_888, 2); 

我的圖像處理算法需要一個RGB圖像作爲輸入,所以我需要從YUV轉換爲RGB。要做到這一點我用ScriptIntrinsicYuvToRGB

private static Bitmap YUV_420_888_toRGBIntrinsics(Image image) { 

    if (image == null) return null; 

    int W = image.getWidth(); 
    int H = image.getHeight(); 

    Image.Plane Y = image.getPlanes()[0]; 
    Image.Plane U = image.getPlanes()[1]; 
    Image.Plane V = image.getPlanes()[2]; 

    int Yb = Y.getBuffer().remaining(); 
    int Ub = U.getBuffer().remaining(); 
    int Vb = V.getBuffer().remaining(); 

    byte[] data = new byte[Yb + Ub + Vb]; 


    Y.getBuffer().get(data, 0, Yb); 
    V.getBuffer().get(data, Yb, Vb); 
    U.getBuffer().get(data, Yb + Vb, Ub); 



    rs = RenderScript.create(context); 
    ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs)); 

    Type.Builder yuvType = new Type.Builder(rs, Element.U8(rs)).setX(data.length); 
    Allocation in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT); 

    Type.Builder rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(W).setY(H); 
    Allocation out = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT); 


    final Bitmap bmpout = Bitmap.createBitmap(W, H, Bitmap.Config.ARGB_8888); 

    in.copyFromUnchecked(data); 

    yuvToRgbIntrinsic.setInput(in); 
    yuvToRgbIntrinsic.forEach(out); 
    out.copyTo(bmpout); 
    image.close(); 
    return bmpout ; 
} 

這種方法是相當快的,因爲我可以在小於20ms轉換1080的圖像。唯一的問題是圖像結果旋轉了270度(即圖像以橫向模式拍攝)。即使我在相機編輯器設置中設置了JPEG_ORIENTATION,captureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION));的結果仍然相同。

這裏我的問題:

  • 是否有辦法找回通過的renderScript內在一個旋轉的圖像?
  • 有沒有不分配內存的「旋轉」功能?
  • 是否有YUV類型的圖像旋轉設置? 我嘗試過的其他解決方案 - 矩陣旋轉,YUV陣列旋轉 - 非常緩慢。此外,我認爲將圖像旋轉90/180/270是一件容易的事情,如果在拍攝後完成,只需要保存行而不是列(以某種方式)。

回答

0

不,沒有內置的YUV輸出旋轉。爲了儘量減少開銷,它始終是從圖像傳感器生產的。您可以閱讀SENSOR_ORIENTATION字段以確定圖像傳感器如何放置在設備上;通常情況下,圖像傳感器的長邊與Android設備的長邊對齊,但仍然會產生兩次有效的旋轉。此外,如果您的目標是讓圖像「直立」,那麼您還需要閱讀加速度計的設備方向,並將其添加到旋轉中。

您正在做一個副本,已經從圖像獲取幀到分配,所以做90/180/270度旋轉然後是相對直接的,雖然內存帶寬密集型。

你也可以看一看谷歌的示例應用程序HdrViewfinderDemo,它將相機數據導入到RenderScript中,而不需要中間拷貝,然後轉換爲RGB以繪製成SurfaceView。它現在沒有旋轉,但可以通過rsGetElementAtYuv_uchar_ *完成90次增量調整查找。