11

RenderScriptには優れたドキュメントが不足していることがわかりました。私が知っていることですが、forEachRSでは、割り当て内の個々のアイテムごとにroot()を実行することです。

画像処理を行うRenderscriptのライブラリを作成しようとしていますが、出発点として、このすばらしい答えに到達しました。ただし、問題は、ブラー操作がピクセルで行われ、各ピクセルに計算の別のループ(ブラー幅のあるn)が必要になることです。マルチコアで実行されていますが、それでも少し遅すぎます。

(2パス)ボックスフィルターを許可するように変更しようとしていますが、セルではなく単一の行または列で作業する必要があります。それで、root()に配列を送信するようにforeachに要求する方法はありますか?

4

1 に答える 1

16

rsForEach は、割り当てに対してのみ操作できます。

画像行ごとに rsForEach 関数で root() を呼び出す必要がある場合は、行数と同じ長さの Allocation を渡してから、内部で操作する必要がある行を特定する必要があります。 root() (同様に、各列で操作します)。その後、RenderScript は作業を分割して、利用可能なリソースで実行する必要があります (マルチコア デバイスで複数の行が同時に処理されます)。

これを行う 1 つの方法は、画像行のオフセット (画像データ配列内) を与える Allocation を渡すことです。root() 内の v_in 引数は行オフセットになります。rsForEach 呼び出しが動作している割り当ては画像データではないため、v_out 引数を使用して画像を書き出すことはできず、出力画像を個別にバインドする必要があります。

これを示す RenderScript を次に示します。

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

rs_allocation gIn;
rs_allocation gOut;
rs_script gScript;

int mImageWidth;
const uchar4 *gInPixels;
uchar4 *gOutPixels;

void init() {
}

static const int kBlurWidth = 20;

//
// This is called per row.
// The row indices are passed in as v_in or you could also use the x argument and multiply it by image width.
//
void root(const int32_t *v_in, int32_t *v_out, const void *usrData, uint32_t x, uint32_t y) {
    float3 blur[kBlurWidth];
    float3 cur_colour = {0.0f, 0.0f, 0.0f};

    for ( int i = 0; i < kBlurWidth; i++) {
        float3 init_colour = {0.0f, 0.0f, 0.0f};
        blur[i] = init_colour;
    }

    int32_t row_index = *v_in;
    int blur_index = 0;

    for ( int i = 0; i < mImageWidth; i++) {
        float4 pixel_colour = rsUnpackColor8888(gInPixels[i + row_index]);

        cur_colour -= blur[blur_index];
        blur[blur_index] = pixel_colour.rgb;
        cur_colour += blur[blur_index];

        blur_index += 1;
        if ( blur_index >= kBlurWidth) {
            blur_index = 0;
        }

        gOutPixels[i + row_index] = rsPackColorTo8888(cur_colour/(float)kBlurWidth);
        //gOutPixels[i + row_index] = rsPackColorTo8888(pixel_colour);
    }
}


void filter() {
    rsDebug("Number of rows:", rsAllocationGetDimX(gIn));
    rsForEach(gScript, gIn, gOut, NULL);
}

これは、次の Java を使用してセットアップされます。

    mBlurRowScript = new ScriptC_blur_row(mRS, getResources(), R.raw.blur_row);

    int row_width = mBitmapIn.getWidth();

    //
    // Create an allocation that indexes each row.
    //
    int num_rows = mBitmapIn.getHeight();
    int[] row_indices = new int[num_rows];
    for ( int i = 0; i < num_rows; i++) {
        row_indices[i] = i * row_width;
    }
    Allocation row_indices_alloc = Allocation.createSized( mRS, Element.I32(mRS), num_rows, Allocation.USAGE_SCRIPT);
    row_indices_alloc.copyFrom(row_indices);

    //
    // The image data has to be bound to the pointers within the RenderScript so it can be accessed
    // from the root() function.
    //
    mBlurRowScript.bind_gInPixels(mInAllocation);
    mBlurRowScript.bind_gOutPixels(mOutAllocation);

    // Pass in the image width
    mBlurRowScript.set_mImageWidth(row_width);

    //
    // Pass in the row indices Allocation as the input. It is also passed in as the output though the output is not used.
    //
    mBlurRowScript.set_gIn(row_indices_alloc);
    mBlurRowScript.set_gOut(row_indices_alloc);
    mBlurRowScript.set_gScript(mBlurRowScript);
    mBlurRowScript.invoke_filter();
于 2012-05-16T11:00:32.710 に答える