A Flutter plugin for accessing TensorFlow Lite API. Supports Classification and Object Detection on both iOS and Android.
- Updated to TensorFlow Lite API v1.12.0.
- No longer accepts parameter
inputSize
andnumChannels
. They will be retrieved from input tensor. numThreads
is moved toTflite.loadModel
.
Add tflite
as a dependency in your pubspec.yaml file.
In android/app/build.gradle
, add the following setting in android
block.
aaptOptions {
noCompress 'tflite'
}
If you get error like "'vector' file not found", please open ios/Runner.xcworkspace
in Xcode, click Runner > Tagets > Runner > Build Settings, search Compile Sources As
, change the value to Objective-C++
;
- Create a
assets
folder and place your label file and model file in it. Inpubspec.yaml
add:
assets:
- assets/labels.txt
- assets/mobilenet_v1_1.0_224.tflite
- Import the library:
import 'package:tflite/tflite.dart';
- Load the model and labels:
String res = await Tflite.loadModel(
model: "assets/mobilenet_v1_1.0_224.tflite",
labels: "assets/labels.txt",
numThreads: 1 // defaults to 1
);
-
See Image Classication and Object Detection below.
-
Release resources:
await Tflite.close();
- Output fomart:
{
index: 0,
label: "person",
confidence: 0.629
}
- Run on image:
var recognitions = await Tflite.runModelOnImage(
path: filepath, // required
imageMean: 0.0, // defaults to 117.0
imageStd: 255.0, // defaults to 1.0
numResults: 2, // defaults to 5
threshold: 0.2 // defaults to 0.1
);
- Run on binary:
var recognitions = await Tflite.runModelOnBinary(
binary: imageToByteListFloat32(image, 224, 127.5, 127.5),// required
numResults: 6, // defaults to 5
threshold: 0.05, // defaults to 0.1
);
Uint8List imageToByteListFloat32(
img.Image image, int inputSize, double mean, double std) {
var convertedBytes = Float32List(1 * inputSize * inputSize * 3);
var buffer = Float32List.view(convertedBytes.buffer);
int pixelIndex = 0;
for (var i = 0; i < inputSize; i++) {
for (var j = 0; j < inputSize; j++) {
var pixel = image.getPixel(j, i);
buffer[pixelIndex++] = (img.getRed(pixel) - mean) / std;
buffer[pixelIndex++] = (img.getGreen(pixel) - mean) / std;
buffer[pixelIndex++] = (img.getBlue(pixel) - mean) / std;
}
}
return convertedBytes.buffer.asUint8List();
}
Uint8List imageToByteListUint8(img.Image image, int inputSize) {
var convertedBytes = Uint8List(1 * inputSize * inputSize * 3);
var buffer = Uint8List.view(convertedBytes.buffer);
int pixelIndex = 0;
for (var i = 0; i < inputSize; i++) {
for (var j = 0; j < inputSize; j++) {
var pixel = image.getPixel(j, i);
buffer[pixelIndex++] = img.getRed(pixel);
buffer[pixelIndex++] = img.getGreen(pixel);
buffer[pixelIndex++] = img.getBlue(pixel);
}
}
return convertedBytes.buffer.asUint8List();
}
- Run on image stream (video frame):
Works with camera plugin 4.0.0. Video format: (iOS) kCVPixelFormatType_32BGRA, (Android) YUV_420_888.
var recognitions = await Tflite.runModelOnFrame(
bytesList: img.planes.map((plane) {return plane.bytes;}).toList(),// required
imageHeight: img.height,
imageWidth: img.width,
imageMean: 127.5, // defaults to 127.5
imageStd: 127.5, // defaults to 127.5
rotation: 90, // defaults to 90, Android only
numResults: 2, // defaults to 5
threshold: 0.1, // defaults to 0.1
);
- Output fomart:
x, y, w, h
are between [0, 1]. You can scale x, w
by the width and y, h
by the height of the image.
{
detectedClass: "hot dog",
confidenceInClass: 0.123,
rect: {
x: 0.15,
y: 0.33,
w: 0.80,
h: 0.27
}
}
- Run on image:
var recognitions = await Tflite.detectObjectOnImage(
path: filepath, // required
model: "SSDMobileNet",
imageMean: 127.5,
imageStd: 127.5,
threshold: 0.4, // defaults to 0.1
numResultsPerClass: 2,// defaults to 5
);
- Run on binary:
var recognitions = await Tflite.detectObjectOnBinary(
binary: imageToByteListUint8(resizedImage, 300), // required
model: "SSDMobileNet",
threshold: 0.4, // defaults to 0.1
numResultsPerClass: 2, // defaults to 5
);
- Run on image stream (video frame):
Works with camera plugin 4.0.0. Video format: (iOS) kCVPixelFormatType_32BGRA, (Android) YUV_420_888.
var recognitions = await Tflite.detectObjectOnFrame(
bytesList: img.planes.map((plane) {return plane.bytes;}).toList(),// required
model: "SSDMobileNet",
imageHeight: img.height,
imageWidth: img.width,
imageMean: 127.5, // defaults to 127.5
imageStd: 127.5, // defaults to 127.5
rotation: 90, // defaults to 90, Android only
numResults: 2, // defaults to 5
threshold: 0.1, // defaults to 0.1
);
- Run on image:
var recognitions = await Tflite.detectObjectOnImage(
path: filepath, // required
model: "YOLO",
imageMean: 0.0,
imageStd: 255.0,
threshold: 0.3, // defaults to 0.1
numResultsPerClass: 2,// defaults to 5
anchors: anchors,// defaults to [0.57273,0.677385,1.87446,2.06253,3.33843,5.47434,7.88282,3.52778,9.77052,9.16828]
blockSize: 32, // defaults to 32
numBoxesPerBlock: 5 // defaults to 5
);
- Run on binary:
var recognitions = await Tflite.detectObjectOnBinary(
binary: imageToByteListFloat32(resizedImage, 416, 0.0, 255.0), // required
model: "YOLO",
threshold: 0.3, // defaults to 0.1
numResultsPerClass: 2,// defaults to 5
anchors: anchors, // defaults to [0.57273,0.677385,1.87446,2.06253,3.33843,5.47434,7.88282,3.52778,9.77052,9.16828]
blockSize: 32, // defaults to 32
numBoxesPerBlock: 5 // defaults to 5
);
- Run on image stream (video frame):
Works with camera plugin 4.0.0. Video format: (iOS) kCVPixelFormatType_32BGRA, (Android) YUV_420_888.
var recognitions = await Tflite.detectObjectOnFrame(
bytesList: img.planes.map((plane) {return plane.bytes;}).toList(),// required
model: "YOLO",
imageHeight: img.height,
imageWidth: img.width,
imageMean: 0, // defaults to 127.5
imageStd: 255.0, // defaults to 127.5
numResults: 2, // defaults to 5
threshold: 0.1, // defaults to 0.1
numResultsPerClass: 2,// defaults to 5
anchors: anchors, // defaults to [0.57273,0.677385,1.87446,2.06253,3.33843,5.47434,7.88282,3.52778,9.77052,9.16828]
blockSize: 32, // defaults to 32
numBoxesPerBlock: 5 // defaults to 5
);
-
Classification and object detection
Refer to the example.
-
Real-time detection
Refer to flutter_realtime_detection.