2016-12-15 1 views
0

レンダスクリプトからScriptIntrinsicYuvToRGBクラスを使用して、YUVからRGBへの変換を試行します(sourceはYUV420形式です)。 私はファイルから読み込んだ3つの生の平面を持っていて、それらをYUVの種類の割り当てに送り込み、ScriptIntrinsicYuvToRGB.forEachに渡します。ScriptIntrinsicYuvToRGBまたはYUV420割り振りが壊れていますか?

彩度チャンネルがbuf [w * h]の場所からすべての値を読み取っているように見えるので、色は正しく処理されますが、色は正しく表示されません - コードサンプルのコメント部分を参照してください。 AllocationがUV面に適切に対処していないと、バグのように見えます。私は、割り当てでrsGetElementAtYuv_uchar_U関数を使用してスクリプトでテストし、任意の座標に対して同じ値(buf [w * h]から)を与えるため、これを仮定します。

ストライド/オフセットなどのYUV形式をさらに指定できるかどうかをすべて検索しましたが、それ以上の設定は見つからなかったElement.DataKind.PIXEL_YUVType.Builder.setYuvFormat(ImageFormat.YUV_420_888)です。

誰か助けてもらえますか?

{ 
     int w = 320, h = 172; 
     ScriptIntrinsicYuvToRGB yc = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs)); 
     { 
     Element elemYUV = Element.createPixel(rs, Element.DataType.UNSIGNED_8, Element.DataKind.PIXEL_YUV); 
     Type typeYUV = new Type.Builder(rs, elemYUV).setX(w).setY(h).setYuvFormat(ImageFormat.YUV_420_888).create(); 
     Allocation yuv = Allocation.createTyped(rs, typeYUV); 
     byte[] buf = new byte[yuv.getBytesSize()]; 
     int offs = 0; 
     for(int i=0; i<3; i++){ 
      int sz = w*h; 
      if(i>0) 
       sz /= 4; 
      InputStream is = new FileInputStream("/sdcard/yuv/"+(i==0 ? 'y' : i==1 ? 'u' : 'v')); 
      int n = is.read(buf, offs, sz); 
      if(n!=sz) 
       throw new AssertionError("!"); 
      offs += sz; 
      is.close(); 
     } 
//    buf[w*h] = 0x40; 
     yuv.copyFrom(buf); 
     yc.setInput(yuv); 
     } 

     Type outType = new Type.Builder(rs, Element.U8_4(rs)).setX(w).setY(h).create(); 
     Allocation out = Allocation.createTyped(rs, outType); 
     yc.forEach(out); 

     int[] buf = new int[out.getBytesSize()/4]; 
     out.copy1DRangeToUnchecked(0, w*h, buf); 

     bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); 
     bm.setPixels(buf, 0, bm.getWidth(), 0, 0, bm.getWidth(), bm.getHeight()); 
     iv.setImageBitmap(bm); 

     yc.destroy(); 
    } 

答えて

0

一つの解決策は、単にU8の割り当てを記入し、カスタムスクリプトでインデックスを自分で行うことです。

#pragma rs_fp_relaxed 
rs_allocation yuv_in; 
uint32_t width; 
uint32_t offset_to_u; 
uint32_t offset_to_v; 
uchar4 RS_KERNEL yuv_to_rgba(uint32_t x, uint32_t y) { 
    uint32_t index = y * width + x; 
    uint32_t uv_index = (y >> 1) * width + (x >> 1); 
    float Y = (float)rsGetElementAt_uchar(yuv_in, index); 
    float U = (float)rsGetElementAt_uchar(yuv_in, uv_index + offset_to_u); 
    float V = (float)rsGetElementAt_uchar(yuv_in, uv_index + offset_to_v); 
    float3 f_out; 
    f_out.r = Y + 1.403f * V; 
    f_out.g = Y - 0.344f * U - 0.714f * V; 
    f_out.b = Y + 1.770f * U; 
    f_out = clamp(f_out, 0.f, 255.f); 
    uchar4 out; 
    out.rgb = convert_uchar3(f_out); 
    out.a = 255; 
    return out; 
} 

のjava:

sc.set_yuv_in(yuv_allocation); 
sc.set_width(width); 
sc.set_offset_to_u(width * height); 
sc.set_offset_to_v(width * height + (width/2 * height/2)); 
sc.forEach_yuv_to_rba(out); 

YUV_420_888は、一般的なYUVの詳細ですアンドロイドの他のYUVリソースからインポートするためのタイプ。 U/Vプレーンのストライド/オフセット値をカスタム変換に役立てるように設定する方法はないと思います。

関連する問題