Как использовать ScriptIntrinsic3DLUT с файлом .cube?

во-первых, я новичок в обработке изображений в Android. У меня есть файл .cube, который был «создан Resolve», то есть 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);
...

есть идеи?


person Rod    schedule 05.09.2014    source источник


Ответы (2)


Разбор файла .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. Мы не можем установить этот массив в куб в ScriptIntrinsic3DLUT с Распределением. Прежде чем сделать это, нам нужно обработать массив с плавающей запятой.

Обработка данных в файле .cube

Как мы знаем, каждый компонент RGB является 8-битным целым, если он имеет 8-битную глубину. 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.
Спасибо.

person Vensent Wang    schedule 09.03.2018

С 3D LUT да, вы должны использовать версию базовой платформы, поскольку в настоящее время нет версии библиотеки поддержки 3D LUT. Ваше распределение 3D LUT должно быть создано путем соответствующего анализа файла, нет встроенной поддержки файлов .cube (или любого другого формата 3D LUT).

person Larry Schiefer    schedule 05.09.2014
comment
Итак, не используйте библиотеку android.support.v8, а вместо этого используйте ядро, то есть android.renderscript. Любые ресурсы о том, как анализировать текстовый файл .cube? Я пытался передать Allocation.createFromString() строковое представление файла, но это не сработало. android.renderscript.RSIllegalArgumentException: LUT должен быть трехмерным. - person Rod; 05.09.2014
comment
Правильно, ядро ​​- единственное, что поддерживает 3DLUT. При этом библиотека поддержки — это место, где происходит активная разработка (исправления ошибок и т. д.), так что это своего рода суждение о том, что использовать. Вы можете столкнуться с другими проблемами, если не используете библиотеку поддержки. Насколько я знаю, нет встроенной поддержки анализа файла куба или любого другого формата 3DLUT. - person Larry Schiefer; 05.09.2014
comment
Я не знаю, почему в документации стало говориться, что активная разработка происходит только в библиотеке поддержки, но это совершенно неверно — я трачу больше времени на android.renderscript.*, чем на android.support.v8.renderscript. * за последнее время. Мы активно разрабатываем обе версии, и библиотека поддержки уступает платформенной версии с точки зрения набора функций, но обеспечивает совместимость с большим количеством устройств. - person Tim Murray; 05.09.2014
comment
Спасибо за разъяснения, @tim-murray! Я действительно подумал, что это странно, что документы заявили, что, поскольку я видел движение в источниках AOSP в обоих. - person Larry Schiefer; 05.09.2014
comment
Мне трудно найти примеры ScriptIntrinsic3DLUT, кто-нибудь может помочь? Я пытаюсь разобраться с разбором файла .cube. - person Rod; 22.09.2014
comment
эй @TimMurray Мне очень-очень жаль, что я так взломал ваш комментарий, но не могли бы вы проверить мой вопрос Renderscript, который очень связан с этим stackoverflow.com/questions/26401503/ ? - person Budius; 16.10.2014