Как выходные значения TensorFlow Lite Float32 представляют изображение? - PullRequest
0 голосов
/ 11 апреля 2020

Issue

Я не могу получить правильные значения изображения из вывода логического вывода TensorFlow Lite.

Использование bitmapOut.copyPixelsFromBuffer возвращает неправильные значения.

Для пример - если я попытаюсь сэмплировать первый пиксель из bitmapIn, используя getPixel (сразу после bitmapIn = getMyInBitmap(); строки), я получу значение -4718617. Сэмплируя первый пиксель из bitmapOut (после bitmapOut.copyPixelsFromBuffer(outBuffer.rewind());), я получаю значение 1040252927.

Также, не нормализуя изображение с помощью NormalizeOp, получаются все значения 0. Так что в настоящее время - я использую NormalizeOp, и после вывода я «денормализую» вывод один за другим - но это действительно очень долго.

Как мне эффективно ввести одно изображение в интерпретатор TensorFlow Lite и получить обратно одно изображение ?

Info

  • Я управляю выводом TensorFlow Lite на Android (Java ).
  • Модель TensorFlow Lite принимает изображение RGB 700x700 {1, 700, 700, 3} в качестве входных данных и выдает только синее изображение 700x700 {1, 700, 700, 1} в качестве выходных данных.
  • Входные и выходные данные модели оба типа FLOAT32.

Вот мой код для применения этого вывода к изображению:

Bitmap bitmapIn, bitmapOut;
ByteBuffer inBuffer, outBuffer;

int[] inShape = tfliteInterpreter.getInputTensor(0).shape()
DataType inDataType = tfliteInterpreter.getInputTensor(0).dataType();
int[] outShape = tfliteInterpreter.getOutputTensor(0).shape()
DataType outDataType = tfliteInterpreter.getOutputTensor(0).dataType();

inTensorImage = new TensorImage(inDataType);
outTensorBuffer = TensorBuffer.createFixedSize(outShape, outDataType);

imageProcessor = new ImageProcessor.Builder()
                        .add(new NormalizeOp(0.0f, 255.0f))
                        .build();

bitmapIn = getMyInBitmap();
inTensorImage.load(bitmapIn);
imageProcessor.process(inTensorImage);

inBuffer = inTensorImage.getBuffer();
outBuffer = outTensorBuffer.getBuffer();

tfliteInterpreter.run(inBuffer, outBuffer);

bitmapOut.copyPixelsFromBuffer(outBuffer.rewind());

Ответы [ 2 ]

0 голосов
/ 26 апреля 2020

Я до сих пор не знаю, как использовать Bitmap copyPixelsFromBuffer для перевода байтов изображения из вывода TensorFlow Lite, но вот решение для правильного получения значений изображения:

// create tensor buffers
TensorImage inputBuffer = new TensorImage([DATA_TYPE]);
TensorBuffer outputBuffer = TensorBuffer.createFixedSize([SHAPE], [DATA_TYPE]);
ByteBuffer output = outputBuffer.getBuffer();

// load input bitmap
inputBuffer.load(inputBitmap);

// run inference
tfliteInterpreter.run(inputBuffer.getBuffer(), output.rewind());

// translate inference bytes to bitmap pixels
int i, r, g, b;

float [] floatArray = output.getFloatArray();

for (i = 0; i < floatArray.length; i++) {

    // your RGB logic here:
    // using floatArray[i], r, g, and b

    outputBitmap.setPixel( i - (i / imageSize) * imageSize ,
        i / imageSize, Color.rgb(r, g, b));
}

Если у кого-то есть более эффективный способ или кто-то знает, как использовать copyPixelsFromBuffer, пожалуйста, добавьте свой ответ.

0 голосов
/ 13 апреля 2020

Я боюсь, что «денормализация» является обязательным условием, так как действительно похоже, что модель генерирует выходные данные с плавающей запятой в диапазоне [0,1] (не могли бы вы подтвердить это?), А не байтовое значение в [0-255] чего ожидает «copyPixelsFromBuffer».

Что касается производительности, есть ли у вас числа, например, сколько времени занимает нормализация и денормализация?

...