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
好的,下面是所有重要的部分。它是从工作代码中复制的,希望我没有遗漏任何东西。使用 out
和 out2
分配计算 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);
}
我可以毫无问题地将 ScriptIntrinsicConvolve3x3(或 5x5)函数用于输入和输出分配 U8_4。但是,如果我想将卷积应用于 Sobel 等梯度滤波器,我需要一个浮点类型的输出(而不是 U8_4),因为我还需要考虑负输出值。这个问题已经在 18 个月前在这里提出,但尚未得到答复。非常感谢任何帮助。
Android RenderScript copy allocation in rs file
好的,下面是所有重要的部分。它是从工作代码中复制的,希望我没有遗漏任何东西。使用 out
和 out2
分配计算 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);
}