Juan Rafael Iniesta
Juan Rafael Iniesta

Reputation: 21

TFLite model gives different output in Android than in Kivy App

I'm facing a problem that I can't seem to solve: my tflite model gives me different data when I run it on Python or Android, causing errors and making it crash on Android. I am developing a Kivy app with tflite that detects chess pieces on a chessboard. I converted my YOLOv8 model to tflite format. The problem occurs when performing the inference of an image in this method:

def get_positions(model_path, img_name):
    print("Loading model...")
    interpreter = Interpreter(model_path=model_path)
    interpreter.allocate_tensors()

    input_details = interpreter.get_input_details()
    output_details = interpreter.get_output_details()
    print("Input details:", input_details)
    print("Output details:", output_details)

    print("Loading image...")
    image = cv2.imread(img_name)
    if image is None:
        raise ValueError(f"Could not load the image from {img_name}")

    print("Original image dimensions:", image.shape)
    image_height = input_details[0]['shape'][1]
    image_width = input_details[0]['shape'][2]
    resized_image = cv2.resize(image, (image_width, image_height))
    input_image = np.array(resized_image, dtype=np.float32) / 255.0
    input_image = input_image[np.newaxis, :]
    print("Resized image dimensions:", input_image.shape)

    interpreter.set_tensor(input_details[0]['index'], input_image)
    interpreter.invoke()

    output = interpreter.get_tensor(output_details[0]['index'])
    output = output[0]
    output = output.T
    print("Model output:", output)

    boxes_xywh = output[..., :4]
    scores = np.max(output[..., 4:], axis=1)
    print("Scores:", scores)
    classes = np.argmax(output[..., 4:], axis=1)

    indices = cv2.dnn.NMSBoxes(boxes_xywh.tolist(), scores.tolist(), confidence_threshold, iou_threshold)
    print("Indices after NMS:", indices)

    results = []
    for i in indices:
        if scores[i] >= confidence_threshold:
            x_center, y_center, width, height = boxes_xywh[i]
            x_center, width = x_center * image_width, width * image_width
            y_center, height = y_center * image_height, height * image_height
            x_center /= image_width
            y_center /= image_height
            width /= image_width
            height /= image_height

            result = {
                'class_id': classes[i],
                'class_name': CLASSES[classes[i]],
                'x_center': x_center,
                'y_center': y_center,
                'width': width,
                'height': height,
                'confidence': scores[i]
            }
            print("Result:", result)
            results.append(result)

    return results

On my computer, it works as expected, but when I create an APK on Android, it crashes because the appropriate data is not generated.

Here are the debug logs from my PC (works well)

\`Loading model... INFO: Created TensorFlow Lite XNNPACK delegate for CPU. Input details: \[{'name': 'inputs_0', 'index': 0, 'shape': array(\[  1, 640, 640,   3\], dtype=int32), 'shape_signature': array(\[  1, 640, 640,   3\], dtype=int32), 'dtype': \<class 'numpy.float32'\>, 'quantization': (0.0, 0), 'quantization_parameters': {'scales': array(\[\], dtype=float32), 'zero_points': array(\[\], dtype=int32), 'quantized_dimension': 0}, 'sparsity_parameters': {}}\] Output details: \[{'name': 'Identity', 'index': 409, 'shape': array(\[   1,   17, 8400\], dtype=int32), 'shape_signature': array(\[   1,   17, 8400\], dtype=int32), 'dtype': \<class 'numpy.float32'\>, 'quantization': (0.0, 0), 'quantization_parameters': {'scales': array(\[\], dtype=float32), 'zero_points': array(\[\], dtype=int32), 'quantized_dimension': 0}, 'sparsity_parameters': {}}\] Loading image... Original image dimensions: (1181, 1690, 3) Resized image dimensions: (1, 640, 640, 3) Model output: \[\[1.1006817e-02 3.4101062e-02 1.9614611e-02 ... 2.6802209e-05   3.2099266e-05 2.3671286e-05\]  \[3.3980943e-02 1.1495238e-02 5.1065966e-02 ... 3.0108062e-05   2.4680974e-05 3.4402736e-05\]  \[4.6541955e-02 7.9353973e-03 6.3635595e-02 ... 1.8403694e-05   4.7014169e-06 2.9310922e-05\]  ...  \[8.8734090e-01 9.7479749e-01 1.9226933e-01 ... 2.3383725e-06   1.9063839e-06 8.1505220e-07\]  \[9.3079507e-01 9.7354954e-01 1.9993711e-01 ... 2.2026159e-06   2.1150520e-06 8.2314017e-07\]  \[9.7550833e-01 9.7113740e-01 1.7806405e-01 ... 1.6881496e-06   1.1987435e-06 6.0122733e-07\]\] Scores: \[4.7006957e-05 8.5894673e-05 4.0709678e-05 ... 3.7478815e-06 3.3213523e-06  2.8609916e-06\] Indices after NMS: \[7601 7853 7668 6563 7878 7088 7262 7287 6536 2125 6607 3547 6808 5907  7688 1336 6896 6972 7068 2867 4295 7497 5086  448 4266 5798  705 7077  6478 6483 7242\] Result: {'class_id': 7, 'class_name': 'white bishop', 'x_center': 0.05852939561009407, 'y_center': 0.773659348487854, 'width': 0.08957379311323166, 'height': 0.14608508348464966, 'confidence': 0.92357063} Result: {'class_id': 12, 'class_name': 'white rook', 'x_center': 0.3321531414985657, 'y_center': 0.8937365412712097, 'width': 0.0860576331615448, 'height': 0.13431024551391602, 'confidence': 0.9208999} Result: {'class_id': 3, 'class_name': 'black knight', 'x_center': 0.7246953248977661, 'y_center': 0.7933675646781921, 'width': 0.0967983603477478, 'height': 0.13826501369476318, 'confidence': 0.9208062} ..........  .......... \`

And from my Android app (it crashes)\`

`Loading model... 05-03 16:37:36.598  6567 30025 I python  : Input details: [{'name': 'inputs_0', 'index': 0, 'shape': array([  1, 640, 640,   3], dtype=int32), 'shape_signature': array([  1, 640, 640,   3], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0), 'quantization_parameters': {'scales': array([], dtype=float32), 'zero_points': array([], dtype=int32), 'quantized_dimension': 0}, 'sparsity_parameters': {}}] 05-03 16:37:36.599  6567 30025 I python  : Output details: [{'name': 'Identity', 'index': 409, 'shape': array([   1,   17, 8400], dtype=int32), 'shape_signature': array([   1,   17, 8400], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0), 'quantization_parameters': {'scales': array([], dtype=float32), 'zero_points': array([], dtype=int32), 'quantized_dimension': 0}, 'sparsity_parameters': {}}] 05-03 16:37:36.599  6567 30025 I python  : Loading image... 05-03 16:37:36.654  6567 30025 I python  : Original image dimensions: (1181, 1690, 3) 05-03 16:37:36.667  6567 30025 I python  : Resized image dimensions: (1, 640, 640, 3) 05-03 16:37:39.163  6567 30025 I python  : Model output: [[1.1006776e-02 3.4101110e-02 1.9614521e-02 ... 2.6802416e-05 05-03 16:37:39.163  6567 30025 I python  :   3.2099608e-05 2.3671355e-05] 05-03 16:37:39.163  6567 30025 I python  :  [3.3980943e-02 1.1495264e-02 5.1065952e-02 ... 3.0108265e-05 05-03 16:37:39.163  6567 30025 I python  :   2.4681047e-05 3.4402743e-05] 05-03 16:37:39.163  6567 30025 I python  :  [4.6541952e-02 7.9354066e-03 6.3635573e-02 ... 1.8403680e-05 05-03 16:37:39.163  6567 30025 I python  :   4.7014123e-06 2.9310897e-05] 05-03 16:37:39.163  6567 30025 I python  :  ... 05-03 16:37:39.163  6567 30025 I python  :  [8.8734090e-01 9.7479749e-01 1.9226938e-01 ... 2.3383748e-06 05-03 16:37:39.163  6567 30025 I python  :   1.9063839e-06 8.1505374e-07] 05-03 16:37:39.163  6567 30025 I python  :  [9.3079507e-01 9.7354960e-01 1.9993705e-01 ... 2.2026243e-06 05-03 16:37:39.163  6567 30025 I python  :   2.1150458e-06 8.2314176e-07] 05-03 16:37:39.163  6567 30025 I python  :  [9.7550833e-01 9.7113740e-01 1.7806411e-01 ... 1.6881464e-06 05-03 16:37:39.163  6567 30025 I python  :   1.1987436e-06 6.0122733e-07]] 05-03 16:37:39.164  6567 30025 I python  : Scores: [4.7007226e-05 8.5895088e-05 4.0709638e-05 ... 3.7478853e-06 3.3213526e-06 05-03 16:37:39.164  6567 30025 I python  :  2.8609834e-06] 05-03 16:37:39.180  6567 30025 I python  : Indices after NMS: [[7601] 05-03 16:37:39.180  6567 30025 I python  :  [7853] 05-03 16:37:39.180  6567 30025 I python  :  [7668] 05-03 16:37:39.180  6567 30025 I python  :  [6563] 05-03 16:37:39.180  6567 30025 I python  :  [7878] 05-03 16:37:39.180  6567 30025 I python  :  [7088] 05-03 16:37:39.180  6567 30025 I python  :  [7262] 05-03 16:37:39.180  6567 30025 I python  :  [7287] 05-03 16:37:39.180  6567 30025 I python  :  [6536] 05-03 16:37:39.180  6567 30025 I python  :  [2125] 05-03 16:37:39.180  6567 30025 I python  :  [6607] 05-03 16:37:39.180  6567 30025 I python  :  [3547] 05-03 16:37:39.180  6567 30025 I python  :  [6808] 05-03 16:37:39.180  6567 30025 I python  :  [5907] 05-03 16:37:39.180  6567 30025 I python  :  [7688] 05-03 16:37:39.180  6567 30025 I python  :  [1336] 05-03 16:37:39.180  6567 30025 I python  :  [6896] 05-03 16:37:39.180  6567 30025 I python  :  [6972] 05-03 16:37:39.180  6567 30025 I python  :  [7068] 05-03 16:37:39.180  6567 30025 I python  :  [2867] 05-03 16:37:39.180  6567 30025 I python  :  [4295] 05-03 16:37:39.180  6567 30025 I python  :  [7497] 05-03 16:37:39.180  6567 30025 I python  :  [5086] 05-03 16:37:39.180  6567 30025 I python  :  [ 448] 05-03 16:37:39.180  6567 30025 I python  :  [4266] 05-03 16:37:39.180  6567 30025 I python  :  [5798] 05-03 16:37:39.180  6567 30025 I python  :  [ 705] 05-03 16:37:39.180  6567 30025 I python  :  [7077] 05-03 16:37:39.180  6567 30025 I python  :  [6478] 05-03 16:37:39.180  6567 30025 I python  :  [6483] 05-03 16:37:39.180  6567 30025 I python  :  [7242]] 05-03 16:37:39.181  6567 30025 I python  : [INFO   ] [Base        ] Leaving application in progress... 05-03 16:37:39.181  6567 30025 I python  :  Traceback (most recent call last): 05-03 16:37:39.181  6567 30025 I python  :    File "/home/jr/Desktop/Kivy/main/.buildozer/android/app/main.py", line 165, in <module> 05-03 16:37:39.181  6567 30025 I python  :    File "/home/jr/Desktop/Kivy/main/.buildozer/android/platform/build-arm64-v8a/build/python-installs/myapp/arm64-v8a/kivy/app.py", line 956, in run 05-03 16:37:39.182  6567 30025 I python  :    File "/home/jr/Desktop/Kivy/main/.buildozer/android/platform/build-arm64-v8a/build/python-installs/myapp/arm64-v8a/kivy/base.py", line 574, in runTouchApp 05-03 16:37:39.182  6567 30025 I python  :    File "/home/jr/Desktop/Kivy/main/.buildozer/android/platform/build-arm64-v8a/build/python-installs/myapp/arm64-v8a/kivy/base.py", line 339, in mainloop 05-03 16:37:39.182  6567 30025 I python  :    File "/home/jr/Desktop/Kivy/main/.buildozer/android/platform/build-arm64-v8a/build/python-installs/myapp/arm64-v8a/kivy/base.py", line 383, in idle 05-03 16:37:39.182  6567 30025 I python  :    File "/home/jr/Desktop/Kivy/main/.buildozer/android/platform/build-arm64-v8a/build/python-installs/myapp/arm64-v8a/kivy/base.py", line 334, in dispatch_input 05-03 16:37:39.182  6567 30025 I python  :    File "/home/jr/Desktop/Kivy/main/.buildozer/android/platform/build-arm64-v8a/build/python-installs/myapp/arm64-v8a/kivy/base.py", line 263, in post_dispatch_input 05-03 16:37:39.183  6567 30025 I python  :    File "kivy/_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch 05-03 16:37:39.183  6567 30025 I python  :    File "/home/jr/Desktop/Kivy/main/.buildozer/android/platform/build-arm64-v8a/build/python-installs/myapp/arm64-v8a/kivy/core/window/__init__.py", line 1709, in on_motion 05-03 16:37:39.183  6567 30025 I python  :    File "kivy/_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch 05-03 16:37:39.183  6567 30025 I python  :    File "/home/jr/Desktop/Kivy/main/.buildozer/android/platform/build-arm64-v8a/build/python-installs/myapp/arm64-v8a/kivy/core/window/__init__.py", line 1726, in on_touch_down 05-03 16:37:39.184  6567 30025 I python  :    File "kivy/_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch 05-03 16:37:39.184  6567 30025 I python  :    File "/home/jr/Desktop/Kivy/main/.buildozer/android/platform/build-arm64-v8a/build/python-installs/myapp/arm64-v8a/kivy/uix/screenmanager.py", line 1210, in on_touch_down 05-03 16:37:39.184  6567 30025 I python  :    File "/home/jr/Desktop/Kivy/main/.buildozer/android/platform/build-arm64-v8a/build/python-installs/myapp/arm64-v8a/kivy/uix/widget.py", line 589, in on_touch_down 05-03 16:37:39.184  6567 30025 I python  :    File "kivy/_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch 05-03 16:37:39.184  6567 30025 I python  :    File "/home/jr/Desktop/Kivy/main/.buildozer/android/platform/build-arm64-v8a/build/python-installs/myapp/arm64-v8a/kivy/uix/relativelayout.py", line 306, in on_touch_down 05-03 16:37:39.185  6567 30025 I python  :    File "/home/jr/Desktop/Kivy/main/.buildozer/android/platform/build-arm64-v8a/build/python-installs/myapp/arm64-v8a/kivy/uix/widget.py", line 589, in on_touch_down 05-03 16:37:39.185  6567 30025 I python  :    File "kivy/_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch 05-03 16:37:39.185  6567 30025 I python  :    File "/home/jr/Desktop/Kivy/main/.buildozer/android/platform/build-arm64-v8a/build/python-installs/myapp/arm64-v8a/kivy/uix/widget.py", line 589, in on_touch_down 05-03 16:37:39.185  6567 30025 I python  :    File "kivy/_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch 05-03 16:37:39.185  6567 30025 I python  :    File "/home/jr/Desktop/Kivy/main/.buildozer/android/platform/build-arm64-v8a/build/python-installs/myapp/arm64-v8a/kivy/uix/behaviors/button.py", line 151, in on_touch_down 05-03 16:37:39.186  6567 30025 I python  :    File "kivy/_event.pyx", line 727, in kivy._event.EventDispatcher.dispatch 05-03 16:37:39.186  6567 30025 I python  :    File "kivy/_event.pyx", line 1307, in kivy._event.EventObservers.dispatch 05-03 16:37:39.186  6567 30025 I python  :    File "kivy/_event.pyx", line 1231, in kivy._event.EventObservers._dispatch 05-03 16:37:39.186  6567 30025 I python  :    File "/home/jr/Desktop/Kivy/main/.buildozer/android/app/main.py", line 139, in scan_and_analyze 05-03 16:37:39.186  6567 30025 I python  :    File "/home/jr/Desktop/Kivy/main/.buildozer/android/app/main_model.py", line 13, in main 05-03 16:37:39.187  6567 30025 I python  :    File "/home/jr/Desktop/Kivy/main/.buildozer/android/app/model_tflite.py", line 71, in get_positions 05-03 16:37:39.187  6567 30025 I python  :  ValueError: not enough values to unpack (expected 4, got 1)`

Upvotes: 1

Views: 61

Answers (1)

Juan Rafael Iniesta
Juan Rafael Iniesta

Reputation: 21

Ok, i solved it. This should be like this:

for i in indices.flatten():
    if scores[i] >= confidence_threshold:
        x_center, y_center, width, height = boxes_xywh[i]
        

The problem was that the array was two-dimensional, not one-dimensional. As for why it worked well in VSCode, I don't know...

Upvotes: 1

Related Questions