/ / ¿Cómo escribir una multiplicación de convolución en Android Renderscript? - Android, convolución, renderscript

¿Cómo escribir una multiplicación de convolución en Android Renderscript? - Android, convolución, renderscript

Soy nuevo en Android Renderscript. Necesito escribir una multiplicación de convolución en RenderScript ya que la aplicación final se ejecutará en Android. El flujo de datos será una imagen. Más específicamente, no puedo escribir la lógica central usando la funcionalidad forEach, aunque puedo hacerlo en Java, ¡pero acelerarlo demasiado lento! ¡Por favor ayuda! Steve

Respuestas

8 para la respuesta № 1

Durante la llamada rsForEach (u otro Renderscriptfunción), puede acceder a los píxeles vecinos de la imagen original (o cualquier tipo de datos que esté utilizando) vinculando la asignación de la imagen original a un puntero dentro del Renderscript donde luego se puede acceder como una matriz. Aquí hay un ejemplo basado en el ejemplo HelloCompute:

#pragma version(1)
#pragma rs java_package_name(com.android.example.hellocompute)

rs_allocation gIn;
rs_allocation gOut;
rs_script gScript;

static int mImageWidth;
const uchar4 *gPixels;

const float4 kWhite = {
1.0f, 1.0f, 1.0f, 1.0f
};
const float4 kBlack = {
0.0f, 0.0f, 0.0f, 1.0f
};

void init() {
}

static const int kBlurWidth = 20;
static const float kMultiplier = 1.0f / (float)(kBlurWidth * 2 + 1);

void root(const uchar4 *v_in, uchar4 *v_out, const void *usrData, uint32_t x, uint32_t y) {
float4 original = rsUnpackColor8888(*v_in);

float4 colour = original * kMultiplier;

int y_component = mImageWidth * y;

for ( int i = -kBlurWidth; i < 0; i++) {
float4 temp_colour;

if ( (int)x + i >= 0) {
temp_colour = rsUnpackColor8888(gPixels[x+i + y_component]);
}
else {
temp_colour = kWhite;
}

colour += temp_colour * kMultiplier;
}
for ( int i = 1; i <= kBlurWidth; i++) {
float4 temp_colour;

if ( x + i < mImageWidth) {
temp_colour = rsUnpackColor8888(gPixels[x+i + y_component]);
}
else {
temp_colour = kWhite;
}

colour += temp_colour * kMultiplier;
}

colour.a = 1.0f;
*v_out = rsPackColorTo8888(colour);
}


void filter() {
mImageWidth = rsAllocationGetDimX(gIn);
rsDebug("Image size is ", rsAllocationGetDimX(gIn), rsAllocationGetDimY(gOut));
rsForEach(gScript, gIn, gOut, NULL);
}

Llamado de la siguiente Java. Tenga en cuenta la llamada a mScript.bind_gPixels (mInAllocation) que une los datos de la imagen original al puntero gPixel en el Renderscript y, por lo tanto, hace que los datos de la imagen estén disponibles como una matriz.

    mRS = RenderScript.create(this);

mInAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
Allocation.MipmapControl.MIPMAP_NONE,
Allocation.USAGE_SCRIPT);
mOutAllocation = Allocation.createTyped(mRS, mInAllocation.getType());

mScript = new ScriptC_blur(mRS, getResources(), R.raw.blur);

mScript.bind_gPixels(mInAllocation);

mScript.set_gIn(mInAllocation);
mScript.set_gOut(mOutAllocation);
mScript.set_gScript(mScript);
mScript.invoke_filter();
mOutAllocation.copyTo(mBitmapOut);