Teachable Machine导出的TFLite模型在Flutter中仅识别首个类别问题
Flutter中Teachable Machine模型识别异常的解决方案
问题分析
在Teachable Machine中测试正常的模型,迁移到Flutter使用flutter_tflite: ^1.0.1时出现识别异常,始终高置信度识别为类别1,核心原因是图像输入的预处理、旋转、尺寸匹配与模型预期不匹配。
修复步骤及代码调整
1. 匹配模型输入尺寸
Teachable Machine导出的图像分类模型默认输入尺寸为224x224(可在导出页面确认),需在runModelOnFrame中明确指定inputSize参数,确保图像被缩放到模型要求的尺寸。
2. 修正图像旋转角度
手机摄像头的传感器方向与UI显示方向不一致,需根据摄像头的实际传感器方向设置rotation参数,而非固定为0。
3. 确保CameraImage尺寸传递正确
部分设备的CameraImage输出会交换宽高,需根据传感器方向调整传递给模型的宽高值。
4. 验证标签文件一致性
检查labels.txt的类别顺序是否与Teachable Machine中训练的类别顺序完全一致,避免标签映射错误。
修改后的完整代码
import 'dart:math'; import 'package:camera/camera.dart'; import 'package:flutter/material.dart'; import 'package:flutter_tflite/flutter_tflite.dart'; import 'package:get/get.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:weeding_bot/models/object_model.dart'; class ScanController extends GetxController { @override void onInit() { super.onInit(); initCamera(); initTFLite(); } @override void dispose() { super.dispose(); cameraController.dispose(); Tflite.close(); // 释放TFLite资源 } List<ObjectModel> allObjects = []; late CameraController cameraController; late List<CameraDescription> cameras; // 根据Teachable Machine导出的模型参数调整输入尺寸 final int modelInputSize = 224; var isCameraInitialized = false; var cameraCount = 0; var detectorBusy = false; initCamera() async { if (await Permission.camera.request().isGranted) { cameras = await availableCameras(); cameraController = CameraController(cameras[0], ResolutionPreset.medium); // 降低分辨率提升检测性能 await cameraController.initialize().then((value) { cameraController.startImageStream((image) { cameraCount++; if (cameraCount % 10 == 0) { cameraCount = 0; objectDetector(image); } }); update(); }); isCameraInitialized = true; update(); } else { debugPrint("未获取相机权限"); } update(); } objectDetector(CameraImage frame) async { try { if (detectorBusy) { debugPrint("检测器繁忙,跳过当前帧"); return; } detectorBusy = true; // 根据传感器方向调整旋转角度和宽高 final int rotation = cameraController.description.sensorOrientation; final int imageWidth = rotation == 90 || rotation == 270 ? frame.height : frame.width; final int imageHeight = rotation == 90 || rotation == 270 ? frame.width : frame.height; var detector = await Tflite.runModelOnFrame( bytesList: frame.planes.map((e) => e.bytes).toList(), imageHeight: imageHeight, imageWidth: imageWidth, imageMean: 127.5, // 匹配Teachable Machine的预处理规则 imageStd: 127.5, rotation: rotation, // 使用摄像头实际旋转角度 numResults: 5, threshold: 0.1, inputSize: modelInputSize); // 指定模型输入尺寸 if (detector != null) { debugPrint("识别结果: $detector"); // 可选:更新UI显示识别结果 // allObjects = detector.map((item) => ObjectModel.fromMap(item)).toList(); // update(); } } catch (e) { debugPrint("识别错误: $e"); } finally { detectorBusy = false; } } initTFLite() async { await Tflite.loadModel( model: "assets/trainedModel/weedDetector.tflite", labels: "assets/trainedModel/labels.txt", ); } }
额外排查点
- 检查
assets目录下的模型和标签文件是否正确配置在pubspec.yaml中:assets: - assets/trainedModel/weedDetector.tflite - assets/trainedModel/labels.txt - 测试时确保光线充足,拍摄目标与Teachable Machine训练时的场景、角度尽量一致
- 若仍有问题,可尝试将图像转换为RGB格式后再输入模型(flutter_tflite支持直接传入RGB字节数组)
内容的提问来源于stack exchange,提问作者Juan Pablo Arango Lizcano
相关产品推荐
相关产品推荐

