如何将ScriptIntrinsic3DLUT与.cube文件一起使用?

时间:2014-09-05 13:02:26

标签: java android renderscript

首先,我是Android中图像处理的新手。我有一个“生成由Resolve”的.cube文件,即LUT_3D_SIZE 33.我正在尝试使用android.support.v8.renderscript.ScriptIntrinsic3DLUT来应用查找表来处理图像。我假设我应该使用ScriptIntrinsic3DLUT而不是android.support.v8.renderscript.ScriptIntrinsicLUT,对吗?

我在查找示例代码时遇到问题,所以这就是我到目前为止拼凑的内容。我遇到的问题是如何根据我的.cube文件创建分配?

...
final RenderScript renderScript = RenderScript.create(getApplicationContext());
final ScriptIntrinsic3DLUT scriptIntrinsic3DLUT = ScriptIntrinsic3DLUT.create(renderScript, Element.U8_4(renderScript));

// How to create an Allocation from .cube file?
//final Allocation allocationLut = Allocation.createXXX();

scriptIntrinsic3DLUT.setLUT(allocationLut);

Bitmap bitmapIn = selectedImage;
Bitmap bitmapOut = selectedImage.copy(bitmapIn.getConfig(),true);

Allocation aIn = Allocation.createFromBitmap(renderScript, bitmapIn);
Allocation aOut = Allocation.createTyped(renderScript, aIn.getType());

aOut.copyTo(bitmapOut);
imageView.setImageBitmap(bitmapOut);
...

有什么想法吗?

2 个答案:

答案 0 :(得分:0)

使用3D LUT是的,您必须使用核心框架版本,因为此时没有支持库版本的3D LUT。您必须通过适当地解析文件来创建3D LUT分配,不存在对.cube文件(或任何其他3D LUT格式)的内置支持。

答案 1 :(得分:0)

解析.cube文件

首先,您应该做的是解析 .cube 文件。  OpenColorIO显示了如何在C ++中执行此操作。它有一些解析LUT文件的方法,如 .cube .lut 等。 例如,FileFormatIridasCube.cpp显示了如何操作 处理 .cube 文件。

您可以轻松获得尺寸  的 LUT_3D_SIZE 即可。我联系了一位图像处理算法工程师。 这就是他所说的:

  • 一般来说,在行业中,17 ^ 3立方体被认为是预览,33 ^ 3正常,65 ^ 3被认为是最高质量的输出。

请注意,在 .cube 文件中,我们可以获得 3 * LUT_3D_SIZE ^ 3 浮动。 关键点是如何处理float数组。我们无法使用 Allocation 将此数组设置为 ScriptIntrinsic3DLUT 中的多维数据集。 在此之前,我们需要处理float数组。

处理.cube文件中的数据

众所周知,如果它是8位深度,则每个RGB分量都是8位int。 R处于高8位,G处于中间,B处于低8位。通过这种方式,24位int可以包含这些 三个组成部分同时进行。

在.cube文件中,每个数据行包含3个浮点数。 请注意:蓝色组件是第一个!!!

我从试错中得到了这个结论。 (或者有人可以给出更准确的解释。)

每个浮点数表示根据255的组件系数。因此,我们需要计算实数  这三个组成部分的价值:

int getRGBColorValue(float b, float g, float r) {
    int bcol = (int) (255 * clamp(b, 0.f, 1.f));
    int gcol = (int) (255 * clamp(g, 0.f, 1.f));
    int rcol = (int) (255 * clamp(r, 0.f, 1.f));
    return bcol | (gcol << 8) | (rcol << 16);
}

因此我们可以从每个数据行中获取一个整数,其中包含3个浮点数。 最后,我们得到整数数组,其长度为 LUT_3D_SIZE ^ 3 。预计这个数组将是 应用于立方体。

ScriptIntrinsic3DLUT

RsLutDemo显示了如何应用 ScriptIntrinsic3DLUT

RenderScript mRs;
Bitmap mBitmap;
Bitmap mLutBitmap;
ScriptIntrinsic3DLUT mScriptlut;
Bitmap mOutputBitmap;
Allocation mAllocIn;
Allocation mAllocOut;
Allocation mAllocCube;
...
int redDim, greenDim, blueDim;
int[] lut;
if (mScriptlut == null) {
    mScriptlut = ScriptIntrinsic3DLUT.create(mRs, Element.U8_4(mRs));
}
if (mBitmap == null) {
    mBitmap = BitmapFactory.decodeResource(getResources(),
            R.drawable.bugs);

    mOutputBitmap = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), mBitmap.getConfig());

    mAllocIn = Allocation.createFromBitmap(mRs, mBitmap);
    mAllocOut = Allocation.createFromBitmap(mRs, mOutputBitmap);
}
...
// get the expected lut[] from .cube file.
...
Type.Builder tb = new Type.Builder(mRs, Element.U8_4(mRs));
tb.setX(redDim).setY(greenDim).setZ(blueDim);
Type t = tb.create();
mAllocCube = Allocation.createTyped(mRs, t);
mAllocCube.copyFromUnchecked(lut);

mScriptlut.setLUT(mAllocCube);
mScriptlut.forEach(mAllocIn, mAllocOut);

mAllocOut.copyTo(mOutputBitmap);

演示

我已完成演示以展示作品。 您可以在Github上查看 感谢。