For image classification applications on Android, the input needs to be in the form [1,224,224,3], but .tflite file generated by Hugginface scritp receives it in the form [1,3,224,224].
How to change this?
the model input format in a .tflite file generated by the run_image_classification.py script and
model = TFMobileViTForImageClassification.from_pretrained
and converter = tf.lite.TFLiteConverter.from_keras_model(model)
this .tflite file is “channel first”. How to modify it so that it is “channel last”?
See the shape of the input in the image of the .tflite file.
Hi @Andre_Ramos,
For your use case, TensorBuffer class from the LiteRT support library might be useful. It creates and manages tensor buffers for model inputs and outputs means the buffer object holds your input data in a format suitable for feeding as input to your TensorFlow Lite model on Android. Here the tensorbuffer java reference code and modify according to your input Image Data.
import org.tensorflow.lite.support.tensorbuffer.TensorBuffer;
# It will convert your image data to required shape suitable to android env
int[] newShape = new int[]{1, height, width, channels};
TensorBuffer buffer = TensorBuffer.createFixedSize(newShape, DataType.FLOAT32);
buffer.loadBuffer(imageData); #Reshape the input data(image data) as [1, 224,224,3] and loads into the buffer
Thank You
thanks for your reply @LK_Kadali but one problem persists.
How would you adapt the code you sent me for this classifier method?
Can you send me the solution in Java, as it can be converted to Kotlin later.
fun classify(image: Bitmap, rotation: Int) {
if (imageClassifier == null) {
setupImageClassifier()
}
// Inference time is the difference between the system time at the start and finish of the
// process
var inferenceTime = SystemClock.uptimeMillis()
// Create preprocessor for the image.
// See https://www.tensorflow.org/lite/inference_with_metadata/
// lite_support#imageprocessor_architecture
val imageProcessor =
ImageProcessor.Builder()
.build()
var height = 224
var width: Int = 224
var channels: Int = 3
val newShape = intArrayOf(1, height, width, channels)
val buffer = TensorBuffer.createFixedSize(newShape, DataType.FLOAT32)
// Preprocess the image and convert it into a TensorImage for classification.
val tensorImage = imageProcessor.process(TensorImage.fromBitmap(image))
// Carrega os dados da imagem no buffer
buffer.loadBuffer(tensorImage.buffer)
val imageProcessingOptions = ImageProcessingOptions.builder()
.setOrientation(getOrientationFromRotation(rotation))
.build()
val results = imageClassifier?.classify(tensorImage, imageProcessingOptions)
inferenceTime = SystemClock.uptimeMillis() - inferenceTime
imageClassifierListener?.onResults(
results,
inferenceTime,
memoryUsed
)
}
In kotlin, I tried to adapt your code but it still showed the errors below:
java.lang.IllegalArgumentException: Error occurred when initializing ImageClassifier: The input tensor should have dimensions 1 x height x width x 3. Got 1 x 3 x 224 x 224.
java.lang.IllegalArgumentException: The size of byte buffer and the shape do not match. Expected: 602112 Actual: 921600