ScriptIntrincisConvolve3x3:输出分配 float4 而不是 U8_4?

ScriptIntrincisConvolve3x3: Output-Allocation float4 instead of U8_4?

我可以毫无问题地将 ScriptIntrinsicConvolve3x3(或 5x5)函数用于输入和输出分配 U8_4。但是,如果我想将卷积应用于 Sobel 等梯度滤波器,我需要一个浮点类型的输出(而不是 U8_4),因为我还需要考虑负输出值。这个问题已经在 18 个月前在这里提出,但尚未得到答复。非常感谢任何帮助。

Android RenderScript copy allocation in rs file

好的,下面是所有重要的部分。它是从工作代码中复制的,希望我没有遗漏任何东西。使用 outout2 分配计算 Java 中的梯度大小留作 reader 的练习。 ;) 同样,在一个 Renderscript 通道中完成所有操作会更快(也更干净)。

public class MainActivity {
  private RenderScript mRS;
  private Allocation mInAllocation;
  Type.Builder TypeIn;

  private void createScript(Bitmap mBitmapIn) {
    mRS = RenderScript.create(this);

    TypeIn = new Type.Builder(mRS, Element.F32_4(mRS));

    mInAllocation = createFromBitmap_F32_4(mRS, mBitmapIn);

    mScriptConvolve = ScriptIntrinsicConvolve3x3.create(mRS,
            Element.F32_4(mRS));

  }

  private Allocation createFromBitmap_F32_4(RenderScript rs, Bitmap b)
  {
    int w = b.getWidth();
    int h = b.getHeight();
    int idx = 0;

    Allocation atn = Allocation.createTyped(mRS, TypeIn.setX(w).setY(h).create());
    float []temp = new float[w * h * 4];

    for(int y = 0; y < h; y++)
        for(int x = 0; x < w; x++)
        {
            int pix = b.getPixel(x, y);

            temp[idx++] = 255.f;
            temp[idx++] = (float)((pix >>> 16) & 0xff);
            temp[idx++] = (float)((pix >>> 8) & 0xff);
            temp[idx++] = (float)(pix & 0xff);
        }

    atn.copyFrom(temp);

    return atn;
  }

  private void allocationToBitmap(Allocation atn, Bitmap bmp)
  {
    int w = bmp.getWidth();
    int h = bmp.getHeight();
    int idx = 0;

    float []temp = new float[w * h * 4];
    atn.copyTo(temp);

    for(int y = 0; y < h; y++)
        for(int x = 0; x < w; x++)
        {
            int a = 255; idx++;
            int r = Math.min(255, Math.max(0, (int)temp[idx++]));
            int g = Math.min(255, Math.max(0, (int)temp[idx++]));
            int b = Math.min(255, Math.max(0, (int)temp[idx++]));

            bmp.setPixel(x, y, (a << 24 | r << 16 | g << 8 | b));
        }
  }

  private void performFilter(Allocation inAllocation,
                           Bitmap bitmapOut) {

            Allocation out = Allocation.createTyped(mRS, TypeIn.create());
            Allocation out2 = Allocation.createTyped(mRS, TypeIn.create());

            // Emboss filter kernel

            float coefficients[] = {-1, 0, 1, -2, 0, 2, -1, 0, 1};
            float coefficients2[] = {-1, -2, -1, 0, 0, 0, 1, 2, 1};

            mScriptConvolve.setCoefficients(coefficients);
            mScriptConvolve.setInput(inAllocation);
            mScriptConvolve.forEach(out);  // Gx

            mScriptConvolve.setCoefficients(coefficients2);
            mScriptConvolve.setInput(inAllocation);
            mScriptConvolve.forEach(out2); // Gy

            allocationToBitmap(out2, bitmapOut);
  }