am15h / tflite_flutter_plugin

TensorFlow Lite Flutter Plugin
https://pub.dev/packages/tflite_flutter
Apache License 2.0
499 stars 352 forks source link

I/flutter (16401): Failed to run model: Bad state: failed precondition #239

Open uditmahato opened 1 year ago

uditmahato commented 1 year ago
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:tflite_flutter/tflite_flutter.dart';
import 'dart:io';
import 'package:flutter/services.dart' show rootBundle;
import 'package:image/image.dart' as img;

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  File? _image;
  Interpreter? _interpreter;
  List<String>? _classLabels;
  List<dynamic>? _output;
  bool _isModelReady = false;

  @override
  void initState() {
    super.initState();
    loadModel().then((_) {
      setState(() {
        _isModelReady = true;
        print('Model is ready.');
      });
    });
  }

  Future<void> loadModel() async {
    try {
      // Load the model.tflite from the assets directory
      final modelFile = await rootBundle.load('lib/ml/model.tflite');
      if (modelFile == null) {
        print('Error: Model file not found.');
        return;
      }
      final modelUint8List = modelFile.buffer.asUint8List();
      print('Model file loaded successfully.');

      // Initialize the interpreter with the loaded model
      _interpreter = await Interpreter.fromBuffer(modelUint8List);
      if (_interpreter == null) {
        print('Error: Interpreter initialization failed.');
        return;
      }

      // Load the labels.txt from the assets directory
      final labelsData = await rootBundle.loadString('lib/ml/labels.txt');
      if (labelsData == null) {
        print('Error: Labels file not found.');
        return;
      }
      _classLabels = labelsData.split('\n');

      print('Model loaded and interpreter initialized successfully.');
    } catch (e) {
      print('Failed to load model: $e');
    }
  }

  Future<void> _pickImage(ImageSource source) async {
    try {
      final pickedImage = await ImagePicker().pickImage(source: source);
      if (pickedImage == null) return;
      setState(() {
        _image = File(pickedImage.path);
      });
      print('Image picked successfully.');

      // Run model inference on the picked image
      await runModelOnImage();
    } catch (e) {
      print('Failed to pick and process image: $e');
    }
  }

  Future<void> runModelOnImage() async {
    if (_isModelReady && _image != null && _interpreter != null) {
      try {
        // Perform data preprocessing on the input image
        final imageBytes = await _image!.readAsBytes();
        final img.Image? image = img.decodeImage(imageBytes);
        if (image != null) {
          final preprocessedImage = img.copyResizeCropSquare(image, 256);
          final inputImage = preprocessedImage.getBytes();

          // Run model inference
          final output = List.filled(_classLabels!.length, 0.0);
          _interpreter!.run(inputImage.buffer.asUint8List(), output);

          setState(() {
            _output = output;
          });

          print('Model inference successful.');

          // Navigate to the display image page
          Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) => DisplayImagePage(
                image: _image!,
                output: _output,
                classLabels: _classLabels,
              ),
            ),
          );
        } else {
          print('Failed to preprocess image: Image is null.');
        }
      } catch (e) {
        print('Failed to run model: $e');
      }
    } else {
      print('Model is not ready or image is null or interpreter is null.');
    }
  }

  @override
  void dispose() {
    _interpreter?.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Image Picker Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            if (_image != null) Image.file(_image!),
            SizedBox(height: 10.0),
            ElevatedButton(
              onPressed: () => _pickImage(ImageSource.gallery),
              child: Text('Pick Image'),
            ),
            SizedBox(height: 10.0),
            ElevatedButton(
              onPressed: () {
                if (_isModelReady && _image != null && _interpreter != null) {
                  runModelOnImage();
                } else {
                  print(
                      'Cannot predict. Model, image, or interpreter is not ready.');
                }
              },
              child: Text('Predict'),
            ),
          ],
        ),
      ),
    );
  }
}

class DisplayImagePage extends StatelessWidget {
  final File image;
  final List<dynamic>? output;
  final List<String>? classLabels;

  const DisplayImagePage({
    required this.image,
    required this.output,
    required this.classLabels,
  });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Image Display'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Image.file(image),
            SizedBox(height: 20.0),
            if (output != null && classLabels != null)
              Text(
                'Predicted Class: ${output != null ? classLabels![output!.indexOf(output!.reduce((a, b) => a > b ? a : b))] : 'Unknown'}',
                style: TextStyle(fontSize: 18.0),
              ),
          ],
        ),
      ),
    );
  }
}