我需要规范化位图并将其存储在 TensorImage 中.有什么办法可以做到这一点吗?



位图仅包含整数值(0-255(。我需要将每个像素值除以 255。位图被转换为 TensorImage 然后当它传递给预测输出的解释器时调用 getBuffer((。(tflite.run((( 在中间的某个地方,我必须将每个 RGB 像素除以 255。恐怕还有另一个缺点,因为 getBuffer(( 函数返回一个字节缓冲区。 我找不到很多关于TensorFlow lite函数的文档。所以我不确定 tflite.run(( 是否只能接受字节缓冲区。 我正在用Java编码,并且是Android AppD的新手。 请帮忙,因为这种规范化对于预测正确的值至关重要。

下面是在调整大小后将位图转换为张量图像的代码。在这里,我需要将每个像素值除以 255,但被难住了。

private TensorImage resizePic(Bitmap bp) {
ImageProcessor imageProcessor =
new ImageProcessor.Builder()
.add(new ResizeOp(60, 60, ResizeOp.ResizeMethod.BILINEAR))
.build();
TensorImage tImage = new TensorImage(DataType.FLOAT32);
tImage.load(bp);
tImage = imageProcessor.process(tImage);
return tImage;
}

这是运行模型的行

tflite.run(tImage.getBuffer(), probabilityBuffer.getBuffer());

probabilityBuffer 保存输出。

我能够使用以下链接构建合适的函数-

  1. 在 Tensorflow-lite Android 中将位图转换为 ByteBuffer (float(

  2. https://heartbeat.fritz.ai/image-classification-on-android-with-tensorflow-lite-and-camerax-4f72e8fdca79

第二个链接在 Kotlin 中。这是代码:

private ByteBuffer convertBitmapToByteBuffer(Bitmap bp) {
ByteBuffer imgData = ByteBuffer.allocateDirect(Float.BYTES*60*60*3);
imgData.order(ByteOrder.nativeOrder());
Bitmap bitmap = Bitmap.createScaledBitmap(bp,60,60,true);
int [] intValues = new int[60*60];
bitmap.getPixels(intValues, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
// Convert the image to floating point.
int pixel = 0;
for (int i = 0; i < 60; ++i) {
for (int j = 0; j < 60; ++j) {
final int val = intValues[pixel++];
imgData.putFloat(((val>> 16) & 0xFF) / 255.f);
imgData.putFloat(((val>> 8) & 0xFF) / 255.f);
imgData.putFloat((val & 0xFF) / 255.f);
}
}
return imgData;
}

在这里,60是我所需的输入图像高度和宽度。此外,此方法不需要使用 TensorImage。所以 tflite.run(( 的最终调用看起来像这样:

tflite.run(convertBitmapToByteBuffer(bp), probabilityBuffer.getBuffer());

在这里,bp 是位图图像。

训练模型时,不要规范化图像。因此,在部署应用程序时,无需规范化位图图像。

您的第一个参考给出了使用 Opencv 进行转换的示例。这是我想出的有效的方法:

private ByteBuffer getImageDataForTfliteModelOpencv(Bitmap input) {
if (input == null) {
return null;
}
// Allocate output ByteBuffer
ByteBuffer output = ByteBuffer.allocateDirect(1 * TFL_IMAGE_SIZE *
TFL_IMAGE_SIZE * 3 * Float.BYTES);
//
output.order(ByteOrder.nativeOrder());
output.rewind();
Mat bufmat = new Mat();
Mat newmat = new Mat(TFL_IMAGE_SIZE, TFL_IMAGE_SIZE, CvType.CV_32FC3);
Utils.bitmapToMat(input, bufmat);
Imgproc.cvtColor(bufmat, bufmat, Imgproc.COLOR_RGBA2RGB);
bufmat.convertTo(newmat, CvType.CV_32FC3, 1.0/255.0);
//
// Write the image float data to the output ByteBuffer
float buf[] = new float[TFL_IMAGE_SIZE * TFL_IMAGE_SIZE * 3];
newmat.get(0,0, buf); // Get the float data
output.asFloatBuffer().put(buf); // Write it as a stream of bytes
return output;
}

然后,返回的 ByteBuffer 可以很容易地加载到 TensorBuffer 中。我测试了这两种方法,对于 112x112 图像,这种 Opencv 方法的速度大约快 50 毫秒。

如此处所述,使用此处的以下代码将位图转换为ByteBuffer(float32)

private ByteBuffer convertBitmapToByteBuffer(Bitmap bitmap) {
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4 * BATCH_SIZE * inputSize * inputSize * PIXEL_SIZE);
byteBuffer.order(ByteOrder.nativeOrder());
int[] intValues = new int[inputSize * inputSize];
bitmap.getPixels(intValues, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
int pixel = 0;
for (int i = 0; i < inputSize; ++i) {
for (int j = 0; j < inputSize; ++j) {
final int val = intValues[pixel++];
byteBuffer.putFloat((((val >> 16) & 0xFF)-IMAGE_MEAN)/IMAGE_STD);
byteBuffer.putFloat((((val >> 8) & 0xFF)-IMAGE_MEAN)/IMAGE_STD);
byteBuffer.putFloat((((val) & 0xFF)-IMAGE_MEAN)/IMAGE_STD);
}
}
return byteBuffer;
}

我找到了答案:

private TensorImage resizePic(Bitmap bp) {
ImageProcessor imageProcessor =
new ImageProcessor.Builder()
.add(new ResizeOp(60, 60, ResizeOp.ResizeMethod.BILINEAR))
.add(new NormalizeOp(0f, 255f))
.build();
TensorImage tImage = new TensorImage(DataType.FLOAT32);
tImage.load(sourceBitmap);
System.out.println("tensorImage0: " + tImage.getTensorBuffer().getFloatArray()[0]);
tImage = imageProcessor.process(tImage);
System.out.println("tensorImage1: " + tImage.getTensorBuffer().getFloatArray()[0]);
return tImage;
}

终端:

System.out: tensorImage0: 232.0
System.out: tensorImage1: 0.9254902

相关内容

最新更新