简体   繁体   中英

Android: How to expand dimension of image using tensorflow lite in Android

The question itself is self-explanatory. In Python, its quite simple to do that with tf.expand_dims(image, 0). How can I do the same thing in Android? I'm getting error on running the tensorflow model I prepared. It says,

Cannot copy to a TensorFlowLite tensor (input_3) with X bytes from a Java Buffer with Y bytes.

I'm guessing it comes from one less dimension of image. I've run another model which is working fine. So I need to know how to do that. My code snippet:

val contentArray =
        ImageUtils.bitmapToByteBuffer(
            scaledBitmap,
            imageSize,
            imageSize,
            IMAGE_MEAN,
            IMAGE_STD
        )

    val tfliteOptions = Interpreter.Options()
    tfliteOptions.setNumThreads(4)
    val tflite = Interpreter(tfliteModel, tfliteOptions)
    tflite.run(contentArray, segmentationMasks)

fun bitmapToByteBuffer(
  bitmapIn: Bitmap,
  width: Int,
  height: Int,
  mean: Float = 0.0f,
  std: Float = 255.0f
): ByteBuffer {
  val bitmap = scaleBitmapAndKeepRatio(bitmapIn, width, height)
  val inputImage = ByteBuffer.allocateDirect(1 * width * height * 3 * 4)
  inputImage.order(ByteOrder.nativeOrder())
  inputImage.rewind()

  val intValues = IntArray(width * height)
  bitmap.getPixels(intValues, 0, width, 0, 0, width, height)
  var pixel = 0
  for (y in 0 until height) {
    for (x in 0 until width) {
      val value = intValues[pixel++]

      // Normalize channel values to [-1.0, 1.0]. This requirement varies by
      // model. For example, some models might require values to be normalized
      // to the range [0.0, 1.0] instead.
      inputImage.putFloat(((value shr 16 and 0xFF) - mean) / std)
      inputImage.putFloat(((value shr 8 and 0xFF) - mean) / std)
      inputImage.putFloat(((value and 0xFF) - mean) / std)
    }
  }

  inputImage.rewind()
  return inputImage
}

There is JVM/Android equivalent op in the TensorFlow API: https://www.tensorflow.org/jvm/api_docs/java/org/tensorflow/op/core/ExpandDims .

However, if you are using TfLite Interpreter API to run inference on a pre-trained model, then you will most likely want to deal with the array dimensions when you construct and save the model (ie using Python) instead of when you call the interpreter from the Android code.

If what you mean is to expand the dimension by 1 and make the first dimension of size 1, so as to mimic a batch of tensors (the same as when you are training), the ImageProcessor class appears to be taking care of that automatically. So you shouldn't have to do it manually.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM