flutter_mlkit icon indicating copy to clipboard operation
flutter_mlkit copied to clipboard

Diffrent results from plugin and Python script on same model. - SELF SOLVED

Open MichalMisiaszek opened this issue 4 years ago • 3 comments

The example code converts image 224x224x3 into long list where each pixel is recorded as RGB in buffer of length 224x244. In my opinion each channel should be serialized separately so first 224x244 is R channel the G then B. Nevertheless using both method the results of custom not optimized float model are difffrent on Android phone than from Python script processing same image with same model. I am trying almost a week to find difference, any hints ?

MichalMisiaszek avatar Jul 24 '19 06:07 MichalMisiaszek

If you check Google example you can see that image is converted to 4D matrix differently. The 4D array structure flattened to buffer will have diffrent memory structure.

I am trying to find a reason why with this plugin I am getting diffrent results from Python script for the same model using the same image.

bitmap = Bitmap.createScaledBitmap(bitmap, 224, 224, true);

int batchNum = 0;
float[][][][] input = new float[1][224][224][3];
for (int x = 0; x < 224; x++) {
    for (int y = 0; y < 224; y++) {
        int pixel = bitmap.getPixel(x, y);
        // 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.
        input[batchNum][x][y][0] = (Color.red(pixel) - 127) / 128.0f;
        input[batchNum][x][y][1] = (Color.green(pixel) - 127) / 128.0f;
        input[batchNum][x][y][2] = (Color.blue(pixel) - 127) / 128.0f;
    }
}```

MichalMisiaszek avatar Jul 24 '19 15:07 MichalMisiaszek

I spent significant time debugging and I still don't know why same picture gets diffrent results from same model using Python Tensorflow Lite API (correct one) and custom model does not. Any hints how to narrow it down ? I suspect input array to blame but I can really narrow it down.

MichalMisiaszek avatar Jul 27 '19 08:07 MichalMisiaszek

The bug is in example code, please change routine to format:

Uint8List imageToByteListFloat(img.Image image, int _inputSize) {
    //return image.getBytes(format: img.Format.rgb);
    var convertedBytes = Float32List(1 * _inputSize * _inputSize * 3);
    var buffer = Float32List.view(convertedBytes.buffer);
    int pixelIndex = 0;
    for (var i = 0; i < _inputSize; i++) {
      for (var j = 0; j < _inputSize; j++) {
        var pixel = image.getPixel(j, i);
        buffer[pixelIndex] = ((pixel) & 0xFF) / 255.0;
        pixelIndex += 1;
        buffer[pixelIndex] = ((pixel >> 8) & 0xFF) / 255.0;
        pixelIndex += 1;
        buffer[pixelIndex] = ((pixel >> 16) & 0xFF) / 255.0;
        pixelIndex += 1;
      }
    }
    return convertedBytes.buffer.asUint8List();
  }

MichalMisiaszek avatar Sep 06 '19 21:09 MichalMisiaszek