Search code examples
javaandroidtensorflowtensorflow-lite

Cannot copy to a TensorFlowLite tensor (input_1) with 150528 bytes from a Java Buffer with 602112 bytes


I'm trying to use my model in the tflitecamerademo example.

Here is my model enter image description here

The demo crashes with the following reason

java.lang.IllegalArgumentException: Cannot copy to a TensorFlowLite tensor (input_1) with 150528 bytes from a Java Buffer with 602112 bytes.

I initialize the byte buffer following google's example

imgData = ByteBuffer.allocateDirect(4 * DIM_BATCH_SIZE * DIM_IMG_SIZE_X * DIM_IMG_SIZE_Y * DIM_PIXEL_SIZE);

imgData.order(ByteOrder.nativeOrder());

DIM_BATCH_SIZE = 1
DIM_IMG_SIZE_X = 224
DIM_IMG_SIZE_Y = 224
DIM_PIXEL_SIZE = 3

Then I resize the image to the net resolution and convert it to a byte buffer

Bitmap reshapeBitmap = Bitmap.createScaledBitmap(bitmap, 224, 224, false);
convertBitmapToByteBuffer(reshapeBitmap);


private void convertBitmapToByteBuffer(Bitmap bitmap) {
        if (imgData == null) {
            return;
        }
        imgData.rewind();
        bitmap.getPixels(intValues, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
        // Convert the image to floating point.
        int pixel = 0;
        long startTime = SystemClock.uptimeMillis();
        for (int i = 0; i < DIM_IMG_SIZE_X; ++i) {
            for (int j = 0; j < DIM_IMG_SIZE_Y; ++j) {
                final int val = intValues[pixel++];
                imgData.putFloat((((val >> 16) & 0xFF)-IMAGE_MEAN)/IMAGE_STD);
                imgData.putFloat((((val >> 8) & 0xFF)-IMAGE_MEAN)/IMAGE_STD);
                imgData.putFloat((((val) & 0xFF)-IMAGE_MEAN)/IMAGE_STD);
            }
        }
        long endTime = SystemClock.uptimeMillis();
        //Log.d("Timecost to put values into ByteBuffer: " + Long.toString(endTime - startTime));
    }

And last, I run the detection

tflite.run(imgData, labelProbArray);

Here the crash happens due to the input size being different to to buffer size.

Now, if we multiply by hand 1 * 224 * 224 * 3 * 4 we get 602112, the correct size. Why my code is missing the last multiplication.


Solution

  • we can just using ImageProcessor CastOp(DataType.UINT8) to cast the bitmap into uint8.

    ImageProcessor imageProcessor;
    TensorImage xceptionTfliteInput;
    if(IS_INT8){
        imageProcessor =
               new ImageProcessor.Builder()
                                .add(new ResizeOp(INPNUT_SIZE.getHeight(), INPNUT_SIZE.getWidth(), ResizeOp.ResizeMethod.BILINEAR))
                                .add(new NormalizeOp(0, 255))
                                .add(new QuantizeOp(inputQuantParams.getZeroPoint(), inputQuantParams.getScale()))
                                .add(new CastOp(DataType.UINT8))
                                .build();
        xceptionTfliteInput = new TensorImage(DataType.UINT8);
    } else {
        imageProcessor =
              new ImageProcessor.Builder()
                                .add(new ResizeOp(INPNUT_SIZE.getHeight(), INPNUT_SIZE.getWidth(), ResizeOp.ResizeMethod.BILINEAR))
                                .add(new NormalizeOp(0, 255))
                                .build();
         xceptionTfliteInput = new TensorImage(DataType.FLOAT32);
    }
    xceptionTfliteInput.load(bitmap);
    xceptionTfliteInput = imageProcessor.process(xceptionTfliteInput);