0

camera2 apiとRAWイメージフォーマットに関する質問がたくさんありましたが、オンラインで検索してもまだ回答が見つかりませんでした(そのため、私はここにいるのです)。Camera2 api Imageformat.yuv_420_888の結果を回転イメージ

ImageReaderと正面カメラでsetRepeatingRequestを使用して、カメラキャプチャフレームでリアルタイム画像処理を実行しようとしています。

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

私の画像処理アルゴリズムは、RGB画像としてが必要いくつかの以前の記事で示唆したように、私は、30fpsの周りにフレームレートを有するためにRAWフォーマット(具体的Imageformat.yuv_420_888)で画像を取得してい入力、私はYUVからRGBに変換する必要があります。私は私が20ms以下で1080pの画像を変換することができますので、この方法は非常に高速である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 ; 
} 

を使用することができません。唯一の問題は、画像の結果が270度回転していることです(つまり、画像は横長モードで撮影されます)。カメラビルダーの設定でJPEG_ORIENTATIONを設定しても、結果は同じです(captureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION));)。

ここに私の質問:

  • はバックのrenderScript組み込み関数によって回転した画像を取得する方法はありますか?
  • メモリを割り当てない「回転」機能はありますか?
  • YUVタイプの画像回転の設定はありますか? 私が試した他の解決策 - 行列の回転、YUV配列の回転 - はかなり遅いです。さらに、私は90/180/270で画像を回転させることは、撮影した後であれば簡単な作業だと思っています。列の代わりに行を保存する必要があります。

答えて

0

いいえ、YUV出力用の組み込み回転はありません。オーバーヘッドを最小限に抑えるため、イメージセンサからは常にそのまま出力されます。 SENSOR_ORIENTATIONフィールドを読んでイメージセンサーがデバイスにどのように配置されているかを調べることができます。通常、イメージセンサーの長いエッジは、Androidデバイスの長いエッジと並んでいますが、それでも有効な2つの回転が残ります。

また、画像を「直立」にすることが目標である場合は、加速度計からデバイスの向きを読み取って回転に追加する必要があります。

イメージをイメージから割り当てにコピーしているので、90/180/270度のローテーションを行うと、メモリ帯域幅が集中しますが、比較的簡単です。

Googleのサンプルアプリケーションの1つであるHdrViewfinderDemoを見ることもできます。これは、カメラのデータを途中でコピーしないでRenderScriptにパイプし、RGBに変換してSurfaceViewに描画します。現在は回転がありませんが、rsGetElementAtYuv_uchar_ *を使用して行われたルックアップを調整して90刻みで調整できます。