You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TFLite模型在Android与Kivy应用中输出不一致致崩溃

Kivy国际象棋检测APP安卓端推理崩溃问题

问题现象

开发基于Kivy的国际象棋棋子检测APP时,将YOLOv8模型转为TFLite格式后,PC端运行get_positions推理方法完全正常,但打包成Android APK后,应用因模型输出处理异常崩溃。

具体错误为:ValueError: not enough values to unpack (expected 4, got 1),根源是PC端cv2.dnn.NMSBoxes返回一维数组格式的indices,而Android端返回二维数组,导致循环中x_center, y_center, width, height = boxes_xywh[i]执行时索引错误。

推理方法代码

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

解决方案

问题核心是cv2.dnn.NMSBoxes在不同平台返回的indices格式不统一,需要统一处理为一维数组后再遍历:

修改循环前的indices处理逻辑,将二维数组扁平化:

# 统一处理indices格式,兼容一维/二维返回值
indices = cv2.dnn.NMSBoxes(boxes_xywh.tolist(), scores.tolist(), confidence_threshold, iou_threshold)
# 将indices转为一维数组
indices = indices.flatten() if len(indices.shape) > 1 else indices

print("Indices after NMS (flattened):", indices)

results = []
for i in indices:
    # 后续逻辑保持不变
    if scores[i] >= confidence_threshold:
        x_center, y_center, width, height = boxes_xywh[i]
        # ... 剩余代码

也可以用numpy的squeeze方法去除多余维度:

indices = np.squeeze(indices)

这样无论PC还是Android端返回的indices是一维还是二维,都会被转为一维数组,循环中boxes_xywh[i]就能正确获取到4个值,避免解包错误。

内容的提问来源于stack exchange,提问作者Juan Rafael Iniesta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 18:47:03