我想在RenderScript中实现一个Sobel滤镜,uchar4作为输入分配,float []作为输出分配。我不太确定是否可以在RenderScript中使用不同类型的输入和输出分配。我想自己开发解决方案,但是希望得到一些关于最好的Renderscript结构的建议来解决这个问题。我读到的地方,可以使用
float 属性((内核))root(uchar4 * v_in,uint32_t x,uint32_t y){ }
你会推荐这样的方法,还是可以在不使用实际内核的情况下完成,即只是一个函数?提前谢谢。
Sobel(X方向)的我的代码现在看起来如下:
#pragma version(1)
#pragma rs java_package_name(com.example.xxx)
#pragma rs_fp_relaxed
rs_allocation gIn;
int32_t width;
int32_t height;
float __attribute__((kernel)) sobelX(uchar4 *v_in, uint32_t x, uint32_t y) {
float out=0;
if (x>0 && y>0 && x<(width-1) && y<(height-1){
uchar4 c11=rsGetElementAt_uchar4(gIn, x-1, y-1);
uchar4 c21=rsGetElementAt_uchar4(gIn, x, y-1);
uchar4 c31=rsGetElementAt_uchar4(gIn, x+1, y-1);
uchar4 c13=rsGetElementAt_uchar4(gIn, x-1, y+1);
uchar4 c23=rsGetElementAt_uchar4(gIn, x, y+1);
uchar4 c33=rsGetElementAt_uchar4(gIn, x+1, y+1);
float4 f11=convert_float4(c11);
float4 f21=convert_float4(c21);
float4 f31=convert_float4(c31);
float4 f13=convert_float4(c13);
float4 f23=convert_float4(c23);
float4 f33=convert_float4(c33);
out= f11.r-f13.r + 2*(f21.r-f23.r) + f31.r-f33.r;
}
return out;
}
我正在努力的是从Java端传递参数:
float[][] gx = new float[width][height];
ScriptC_sobel script;
script=new ScriptC_sobel(rs);
script.set_width(width) ;
script.set_height(height) ;
script.set_gIn(bmpGray);
Allocation inAllocation = Allocation.createFromBitmap(rs, bmpGray, Allocation.MipmapControl.MIPMAP_NONE,
Allocation.USAGE_SCRIPT);
Allocation outAllocation = Allocation.createTyped(rs, float,2) ;
script.forEach_sobelX(inAllocation, outAllocation);
outAllocation.copyTo(gx) ;
据我所知,为了使用rsGetElementAt函数(访问内核中的相邻数据),我还需要将输入分配设置为脚本全局(rs代码中的rs_allocation gIn)。但是,我不确定如何从Java端处理这种“双重分配”。此外,Java代码中的outAllocation语句可能不正确。具体而言,我不确定,内核是否会将其作为float []或float [] []返回。
答案 0 :(得分:1)
输入和输出可以使用不同的类型。在你的情况下,我实际上会建议:
float __attribute__((kernel)) sobel(unchar4 *v_in, uint32_t x, uint32_t y) {}
您当然希望使用内核,以便多线程执行可以提高性能。
另外,请查看此example of doing 3x3 convolution in RS。
UPDATE:通常,要使用的最佳输入/输出参数取决于您希望此过滤器生成的输出类型 - 它只是幅度吗?然后uint
输出很可能就足够了。
UPDATE2:如果您要使用变量来传递输入分配,那么您在内核参数中就不需要它,即:
float __attribute__((kernel)) sobelX(uint32_t x, uint32_t y)
脚本的其余部分看起来没问题(条件中缺少括号)。至于Java部分,下面我将介绍如何准备输出分配并启动脚本。然后将为输出分配中的每个单元格(即每个浮点数)调用内核。
float[] gx = new float[width * height];
Type.Builder TypeIn = new Type.Builder(mRS, Element.F32(mRS));
TypeIn.setX(width).setY(height);
Allocation outAllocation = Allocation.createTyped(mRS, TypeIn.create());
mScript.forEach_sobelX(outAllocation);