flutter_tflite_image_classification_engine 0.0.1
flutter_tflite_image_classification_engine: ^0.0.1 copied to clipboard
A lightweight Flutter package for running **TensorFlow Lite image classification** with custom `.tflite` models and label files.
flutter_tflite_image_classification_engine #
A lightweight Flutter package for running TensorFlow Lite image classification with custom .tflite models and label files.
flutter_tflite_image_classification_engine allows Flutter developers to classify images using their own TensorFlow Lite models with a clean, flexible, and UI-free API.
This package supports normal image classification and realtime stream image classification.
✨ Features #
- ✅ TensorFlow Lite image classification
- ✅ Custom
.tflitemodel support - ✅ Custom
labels.txtsupport - ✅ Image classification from
File - ✅ Image classification from image path
- ✅ Image classification from image bytes
- ✅ Normal single image classification mode
- ✅ Realtime stream classification mode
- ✅ Auto input tensor shape detection
- ✅ RGB and grayscale image support
- ✅ Configurable confidence threshold
- ✅ Configurable top-K predictions
- ✅ Configurable normalization
- ✅ Optional softmax support
- ✅ Isolate-based image preprocessing
- ✅ ANR-safe processing pattern
- ✅ Structured classification result
- ✅ JSON result support
- ✅ Simple Flutter API
- ✅ No image picker dependency in core package
- ✅ No camera dependency in core package
- ✅ No file picker dependency in core package
🚀 Supported Modes #
| Mode | Description |
|---|---|
| Normal Mode | Classify a single image from file, path, or bytes |
| Realtime Stream Mode | Classify continuous image input using stream |
| Dynamic Model Mode | Load model from asset, file, path, or bytes |
| Dynamic Label Mode | Load labels from asset, file, path, text, or list |
📦 Installation #
Add this package to your pubspec.yaml:
dependencies:
flutter_tflite_image_classification_engine: ^0.0.1
Then run:
flutter pub get
📁 Assets Setup #
Add your model and labels file:
assets/
models/
model.tflite
labels.txt
Register assets in your pubspec.yaml:
flutter:
assets:
- assets/models/model.tflite
- assets/models/labels.txt
⚡ Quick Start #
1. Import package #
import 'dart:io';
import 'package:flutter_tflite_image_classification_engine/flutter_tflite_image_classification_engine.dart';
2. Create classification engine #
Future<FlutterTfliteImageClassificationEngine> createEngine() async {
final FlutterTfliteImageClassificationEngine engine =
await FlutterTfliteImageClassificationEngine.create(
model: TfliteModel.asset('assets/models/model.tflite'),
labels: TfliteLabels.asset('assets/models/labels.txt'),
);
return engine;
}
3. Classify image #
Future<void> classifyImage(File imageFile) async {
final FlutterTfliteImageClassificationEngine engine =
await FlutterTfliteImageClassificationEngine.create(
model: TfliteModel.asset('assets/models/model.tflite'),
labels: TfliteLabels.asset('assets/models/labels.txt'),
);
final ClassificationResult result = await engine.classifyImage(
ImageInput.file(imageFile),
);
print('Best Label: ${result.bestLabel}');
print('Confidence: ${result.bestConfidencePercent}');
engine.close();
}
🧠 Normal Image Classification #
Use classifyImage() for single image classification.
Future<void> runNormalClassification(File imageFile) async {
final FlutterTfliteImageClassificationEngine engine =
await FlutterTfliteImageClassificationEngine.create(
model: TfliteModel.asset('assets/models/model.tflite'),
labels: TfliteLabels.asset('assets/models/labels.txt'),
options: const TfliteClassifierOptions(
mode: ClassificationMode.normal,
topK: 3,
minConfidence: 0.40,
threads: 4,
normalizationType: NormalizationType.zeroToOne,
channelOrder: ChannelOrder.rgb,
interpolation: ResizeInterpolation.linear,
useSoftmax: false,
unknownLabel: 'Unknown',
runPreprocessInIsolate: true,
),
);
final ClassificationResult result = await engine.classifyImage(
ImageInput.file(imageFile),
);
if (result.isSuccess && !result.isUnknown) {
print('Best: ${result.bestLabel}');
print('Confidence: ${result.bestConfidencePercent}');
for (final TflitePrediction prediction in result.predictions) {
print('${prediction.label}: ${prediction.confidencePercent}');
}
} else {
print(result.error ?? result.message ?? 'Classification failed');
}
engine.close();
}
⚡ Realtime Stream Classification #
This package does not open the camera directly.
You can use any camera package in your own app and pass image input stream to this engine.
Future<void> runRealtimeClassification(
Stream<ImageInput> imageStream,
) async {
final FlutterTfliteImageClassificationEngine engine =
await FlutterTfliteImageClassificationEngine.create(
model: TfliteModel.asset('assets/models/model.tflite'),
labels: TfliteLabels.asset('assets/models/labels.txt'),
options: const TfliteClassifierOptions(
mode: ClassificationMode.realtimeStream,
topK: 3,
minConfidence: 0.40,
realtimeOptions: RealtimeClassifierOptions(
frameIntervalMs: 300,
skipBusyFrames: true,
emitSkippedFrames: false,
maxStreamErrors: 5,
),
),
);
engine.classifyImageStream(imageStream).listen((ClassificationResult result) {
if (result.isSkipped) return;
if (result.isSuccess && !result.isUnknown) {
print('${result.bestLabel}: ${result.bestConfidencePercent}');
} else {
print(result.error ?? result.message ?? 'Unknown result');
}
});
}
🔧 Dynamic Model Sources #
You can load your .tflite model in multiple ways:
TfliteModel.asset('assets/models/model.tflite');
TfliteModel.file(File('/storage/emulated/0/model.tflite'));
TfliteModel.path('/storage/emulated/0/model.tflite');
TfliteModel.bytes(modelBytes);
🏷️ Dynamic Label Sources #
You can load labels in multiple ways:
TfliteLabels.asset('assets/models/labels.txt');
TfliteLabels.file(File('/storage/emulated/0/labels.txt'));
TfliteLabels.path('/storage/emulated/0/labels.txt');
TfliteLabels.text('cat\ndog\nbird');
TfliteLabels.list(<String>['cat', 'dog', 'bird']);
🖼️ Dynamic Image Sources #
You can classify image input in multiple ways:
ImageInput.file(File('/storage/emulated/0/image.jpg'));
ImageInput.path('/storage/emulated/0/image.jpg');
ImageInput.bytes(imageBytes);
⚙️ Configuration Options #
const TfliteClassifierOptions(
mode: ClassificationMode.normal,
topK: 3,
minConfidence: 0.40,
threads: 4,
normalizationType: NormalizationType.zeroToOne,
channelOrder: ChannelOrder.rgb,
interpolation: ResizeInterpolation.linear,
useSoftmax: false,
unknownLabel: 'Unknown',
runPreprocessInIsolate: true,
realtimeOptions: RealtimeClassifierOptions(
frameIntervalMs: 300,
skipBusyFrames: true,
emitSkippedFrames: false,
maxStreamErrors: 5,
),
);
🔢 Normalization Types #
NormalizationType.zeroToOne #
value = pixel / 255.0
NormalizationType.minusOneToOne #
value = (pixel - 127.5) / 127.5
NormalizationType.none #
value = raw pixel value 0..255
📊 Classification Result #
The engine returns a structured ClassificationResult.
final ClassificationResult result = await engine.classifyImage(
ImageInput.file(imageFile),
);
print(result.isSuccess);
print(result.isUnknown);
print(result.isSkipped);
print(result.bestLabel);
print(result.bestConfidence);
print(result.bestConfidencePercent);
print(result.predictions);
print(result.rawScores);
print(result.inferenceTimeMs);
print(result.preprocessTimeMs);
print(result.totalTimeMs);
print(result.toJson());
🏆 Prediction Data #
Each prediction contains index, label, and confidence.
class ExamplePrediction {
const ExamplePrediction({
required this.index,
required this.label,
required this.confidence,
});
final int index;
final String label;
final double confidence;
}
Example:
void printPredictions(ClassificationResult result) {
for (final TflitePrediction prediction in result.predictions) {
print('${prediction.label}: ${prediction.confidencePercent}');
}
}
🔍 Useful Result Helpers #
result.bestLabel;
result.bestConfidence;
result.bestConfidencePercent;
result.top(3);
result.predictionByLabel('cat');
result.labelConfidenceMap;
result.toJson();
📌 Full Usage Example #
import 'dart:io';
import 'package:flutter_tflite_image_classification_engine/flutter_tflite_image_classification_engine.dart';
class ClassificationService {
FlutterTfliteImageClassificationEngine? _engine;
Future<void> load() async {
_engine = await FlutterTfliteImageClassificationEngine.create(
model: TfliteModel.asset('assets/models/model.tflite'),
labels: TfliteLabels.asset('assets/models/labels.txt'),
options: const TfliteClassifierOptions(
mode: ClassificationMode.normal,
topK: 3,
minConfidence: 0.40,
threads: 4,
normalizationType: NormalizationType.zeroToOne,
runPreprocessInIsolate: true,
),
);
}
Future<ClassificationResult> classify(File imageFile) async {
final FlutterTfliteImageClassificationEngine? engine = _engine;
if (engine == null) {
throw Exception('Classification engine is not loaded');
}
return engine.classifyImage(
ImageInput.file(imageFile),
);
}
void dispose() {
_engine?.close();
}
}
🛡️ Performance Tips #
For realtime image classification, follow these rules:
- Do not process every camera frame
- Use frame throttling
- Use a processing lock
- Use low or medium camera resolution
- Do not call classification inside
build() - Load the model once and reuse the same engine
- Stop image stream before disposing camera controller
- Close the engine when the screen is disposed
- Use isolate-based preprocessing for large images
Recommended realtime options:
const RealtimeClassifierOptions(
frameIntervalMs: 300,
skipBusyFrames: true,
emitSkippedFrames: false,
maxStreamErrors: 5,
);
🧪 Example App #
Run the example project:
cd example
flutter clean
flutter pub get
flutter run
The example app can show:
- Normal image classification
- Realtime stream classification
- Camera preview integration
- Classification result overlay
- Top prediction display
📁 Package Structure #
flutter_tflite_image_classification_engine/
├── lib/
│ └── flutter_tflite_image_classification_engine.dart
├── example/
│ └── lib/
│ └── main.dart
├── pubspec.yaml
├── README.md
├── CHANGELOG.md
└── LICENSE
🧱 Platform Support #
| Platform | Status |
|---|---|
| Android | ✅ Supported |
| iOS | ✅ Supported |
| Web | ❌ Not supported |
| Windows | ❌ Not supported |
| macOS | ❌ Not supported |
| Linux | ❌ Not supported |
⚠️ Important Note About Bounding Boxes #
This package is for image classification.
Image classification models return:
label + confidence
They do not return object position or bounding box.
So this package cannot draw a real moving rectangle around objects like object detection models.
For moving object rectangles, use an object detection model such as:
- SSD MobileNet
- YOLO
- EfficientDet
✅ Best For #
- Fruit classification
- Product category classification
- Plant classification
- Food classification
- Document image classification
- Realtime category classification
- Custom TFLite classifier integration
- Lightweight AI feature integration in Flutter apps
🚫 Not Included #
This package does not include:
- Camera UI
- Gallery picker
- File picker
- Object detection bounding box parser
- Model training
- Dataset annotation tools
This keeps the package lightweight, clean, and flexible.
🗺️ Roadmap #
- ✅ Normal image classification
- ✅ Realtime stream classification
- ✅ Dynamic model source
- ✅ Dynamic label source
- ✅ Dynamic image source
- ✅ Structured classification result
- ✅ Isolate-based preprocessing
- ❌ Object detection mode
- ❌ Bounding box parser
- ❌ YOLO output parser
- ❌ SSD MobileNet output parser
- ❌ Image segmentation mode
- ❌ More example apps
❓ Troubleshooting #
Model file not found #
Make sure your model path is correct:
TfliteModel.asset('assets/models/model.tflite');
And make sure the asset is registered:
flutter:
assets:
- assets/models/model.tflite
Labels file not found #
Make sure your labels path is correct:
TfliteLabels.asset('assets/models/labels.txt');
And make sure the labels file is registered:
flutter:
assets:
- assets/models/labels.txt
Wrong prediction result #
Try changing normalization type:
normalizationType: NormalizationType.zeroToOne,
or:
normalizationType: NormalizationType.minusOneToOne,
Also make sure your labels order matches your model output order.
App is slow in realtime mode #
Use these settings:
const TfliteClassifierOptions(
runPreprocessInIsolate: true,
realtimeOptions: RealtimeClassifierOptions(
frameIntervalMs: 300,
skipBusyFrames: true,
),
);
Also use low or medium camera resolution in your app.
🤝 Contributing #
Contributions are welcome.
You can help by adding:
- Object detection mode
- YOLO parser
- SSD parser
- Image segmentation support
- More examples
- Better realtime frame support
- iOS optimization
- Documentation improvements
📄 License #
See the LICENSE file for details.
👨💻 Author #
Created by Nafim Ahmed
Flutter developer focused on AI vision, automation, ERP integrations, and real-time mobile applications.