TensorFlow Lite 的 Float32 输出值如何表示图像?

How do TensorFlow Lite's Float32 output-values represent an image?

问题

我无法从 TensorFlow Lite 推理的输出中获取正确的图像值。

使用 bitmapOut.copyPixelsFromBuffer 得到错误的值。

例如 - 如果我尝试使用 getPixelbitmapIn 中采样第一个像素(就在 bitmapIn = getMyInBitmap(); 行之后),我得到的值是 -4718617。从 bitmapOut 采样第一个像素(在 bitmapOut.copyPixelsFromBuffer(outBuffer.rewind()); 之后)我得到一个值 1040252927.

此外,不使用 NormalizeOp 规范化图像,获取所有 0 值。所以目前 - 我使用 NormalizeOp,在推理之后我是 "denormalizing" 一个一个地输出 - 但这需要很长时间。

如何高效地将单张图像输入 TensorFlow Lite 解释器,并返回单张图像

信息

这是我在图像上应用该推理的代码:

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());

恐怕 "de-normalizing" 是必须具备的,因为看起来模型确实在 [0,1] 范围内生成浮点输出(你能帮忙确认一下吗?)而不是字节"copyPixelsFromBuffer" 期望的 [0-255] 中的值。

关于性能问题,您是否有任何数字,例如规范化和非规范化需要多长时间?

我仍然不知道如何使用 BitmapcopyPixelsFromBuffer 从 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,请添加您的答案。