Flutter TensorFlow Lite运行时错误:张量形状不匹配问题
问题排查与解决
错误原因
你遇到的张量形状不匹配问题,核心是tflite库的detectObjectOnFrame方法中指定的model: "YOLO",其内置解析逻辑预期模型输出为[1, 20, 20, 30]这类网格结构张量,但你的自定义模型mymodel.tflite实际输出是扁平化的[1, 25200, 6]张量(25200为检测框总数,6包含坐标、置信度、类别信息),两者结构不兼容导致解析失败。
另外代码存在语法错误:plane.bytes.; 多了一个句号,应改为plane.bytes。
解决方法
方法一:改用自定义模型模式手动解析输出
将detectObjectOnFrame的model参数改为"custom",绕过库内置的YOLO解析逻辑,手动处理模型输出的原始张量数据,这是最直接的解决方案:
Tflite.detectObjectOnFrame( bytesList: img.planes.map((plane) { return plane.bytes; // 修复语法错误 }).toList(), model: widget.model == mymodel ? "custom" : "SSDMobileNet", // 切换为custom模式 imageHeight: img.height, imageWidth: img.width, imageMean: widget.model == mymodel ? 0 : 127.5, imageStd: widget.model == mymodel ? 255.0 : 127.5, numResultsPerClass: 1, threshold: widget.model == mymodel ? 0.2 : 0.4, ).then((recognitions) { int endTime = DateTime.now().millisecondsSinceEpoch; print("Detection took ${endTime - startTime}"); // 手动解析custom模式返回的原始张量 if (widget.model == mymodel && recognitions != null) { // 模型输出为[1, 25200, 6],取第一个维度下的所有检测框 List<dynamic> boxes = recognitions[0]; List<Map<String, dynamic>> parsedResults = []; for (var box in boxes) { double confidence = box[4]; // 过滤低于阈值的结果 if (confidence >= 0.2) { parsedResults.add({ "x": box[0], // 需根据你的模型输出顺序调整,通常为x,y,w,h "y": box[1], "w": box[2], "h": box[3], "confidence": confidence, "detectedClass": widget.labels[0] // 单类检测直接取第一个标签 }); } } widget.setRecognitions(parsedResults, img.height, img.width); } else { widget.setRecognitions(recognitions!, img.height, img.width); } isDetecting = false; });
方法二:调整模型输出适配YOLO模式
如果坚持使用model: "YOLO",需要重新导出或转换tflite模型,使其输出形状符合tflite库预期的YOLO网格结构(如YOLOv3-tiny的多尺度输出)。但该方式需要修改模型训练或导出流程,复杂度较高,更推荐方法一。
内容的提问来源于stack exchange,提问作者Tanmay Shrivastava
相关产品推荐
相关产品推荐

