对于输入和输出分配同时应用ScriptIntrinsicConvolve3x3(或5x5)函数同样是U8_4也没有问题。但是如果我想将卷积应用于像Sobel这样的梯度滤波器,我需要一个float类型的输出(不是U8_4),因为我还需要考虑NEGATIVE输出值。这个问题在18个月前提出,但尚未得到答复。任何帮助都非常感谢。
答案 0 :(得分:2)
好的,下面你有所有重要的部分。它是从一个正常工作的代码中复制而来的,希望我没有错过任何东西。使用out
和out2
分配在Java中计算梯度幅度是留给读者的练习。 ;)同样,在一个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);
}