I'm trying to load a TFLite model into flutter but I'm getting the exception "failed to load model". I've loaded the asset through the yaml, imported the TFLite plugin and made sure the file path is right but I keep getting the same exception printed. I've tested the model with python and it works so I'm just trying to get it to work with flutter now.
Code:
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:tflite/tflite.dart';
import 'package:image_picker/image_picker.dart';
import 'package:image/image.dart' as img;
void main() {
runApp(MyApp());
}
const String TF = "image_classifier";
//const String yolo = "Tiny YOLOv2";
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: TfliteHome(),
);
}
}
class TfliteHome extends StatefulWidget {
@override
_TfliteHomeState createState() => _TfliteHomeState();
}
class _TfliteHomeState extends State<TfliteHome> {
String _model = TF;
File _image;
double _imageWidth;
double _imageHeight;
bool _busy = false;
List _recognitions;
@override
void initState() {
super.initState();
_busy = true;
loadModel().then((val) {
setState(() {
_busy = false;
});
});
}
loadModel() async {
Tflite.close();
try {
String res;
res = await Tflite.loadModel(
model: "assets/image_classifier.tflite",
labels: "assets/image_labels.txt",
);
print(res);
} on PlatformException {
print("Failed to load the model");
}
}
selectFromImagePicker() async {
var image = await ImagePicker.pickImage(source: ImageSource.gallery);
if (image == null) return;
setState(() {
_busy = true;
});
predictImage(image);
}
predictImage(File image) async {
if (image == null) return;
if (_model == TF) {
await TFModel(image);
}
FileImage(image)
.resolve(ImageConfiguration())
.addListener((ImageStreamListener((ImageInfo info, bool _) {
setState(() {
_imageWidth = info.image.width.toDouble();
_imageHeight = info.image.height.toDouble();
});
})));
setState(() {
_image = image;
_busy = false;
});
}
TFModel(File image) async {
var recognitions = await Tflite.detectObjectOnImage(
path: image.path,
model: "image_classifier",
threshold: 0.3,
imageMean: 0.0,
imageStd: 255.0,
numResultsPerClass: 3);
setState(() {
_recognitions = recognitions;
});
}
List<Widget> renderBoxes(Size screen) {
if (_recognitions == null) return [];
if (_imageWidth == null || _imageHeight == null) return [];
double factorX = screen.width;
double factorY = _imageHeight / _imageHeight * screen.width;
Color blue = Colors.red;
return _recognitions.map((re) {
return Positioned(
left: re["rect"]["x"] * factorX,
top: re["rect"]["y"] * factorY,
width: re["rect"]["w"] * factorX,
height: re["rect"]["h"] * factorY,
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: blue,
width: 3,
)),
child: Text(
"${re["detectedClass"]} ${(re["confidenceInClass"] * 100).toStringAsFixed(0)}%",
style: TextStyle(
background: Paint()..color = blue,
color: Colors.white,
fontSize: 15,
),
),
),
);
}).toList();
}
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
List<Widget> stackChildren = [];
stackChildren.add(Positioned(
top: 0.0,
left: 0.0,
width: size.width,
child: _image == null ? Text("No Image Selected") : Image.file(_image),
));
stackChildren.addAll(renderBoxes(size));
if (_busy) {
stackChildren.add(Center(
child: CircularProgressIndicator(),
));
}
return Scaffold(
appBar: AppBar(
title: Text("TFLite Demo"),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.image),
tooltip: "Pick Image from gallery",
onPressed: selectFromImagePicker,
),
body: Stack(
children: stackChildren,
),
);
}
}
Pubspec.yaml:
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
assets:
- assets/image_classifier.tflite
- assets/image_labels.txt
I think:
should be without the 'assets' in the paths.