diff --git a/example/movinet/README.md b/example/movinet/README.md index 5e82f8c..64d2f3e 100644 --- a/example/movinet/README.md +++ b/example/movinet/README.md @@ -1,16 +1,22 @@ -# movinet +# Action Recognition Movinet -A new Flutter project. +| | Android | iOS | Linux | Mac | Windows | Web | +|------|---------|-----|-------|-----|---------|-----| +| live | ✅ | ✅ | | | | | -## Getting Started +This project is a sample of how to perform action recognition using +TensorFlow Lite in Flutter. It includes support for both Android and IOS. -This project is a starting point for a Flutter application. +## Download model and labels -A few resources to get you started if this is your first Flutter project: +To build the project, you must first download the Movinet TensorFlow Lite +model. You can do this by access https://www.kaggle.com/models/google/movinet +and download movinet model. After downloading the model, you must copy the model +into the `assets` folder. -- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) +## About the sample -For help getting started with Flutter development, view the -[online documentation](https://docs.flutter.dev/), which offers tutorials, -samples, guidance on mobile development, and a full API reference. +- You can use Flutter-supported IDEs such as Android Studio or Visual Studio. + This project has been tested on Android Studio Flamingo. +- Before building, ensure that you have downloaded the model and the labels by + following a set of instructions. diff --git a/example/movinet/assets/images/tfl_logo.png b/example/movinet/assets/images/tfl_logo.png new file mode 100644 index 0000000..2bdcd9a Binary files /dev/null and b/example/movinet/assets/images/tfl_logo.png differ diff --git a/example/movinet/ios/Runner/Info.plist b/example/movinet/ios/Runner/Info.plist index 1c1a2d6..e125c80 100644 --- a/example/movinet/ios/Runner/Info.plist +++ b/example/movinet/ios/Runner/Info.plist @@ -26,6 +26,8 @@ UILaunchStoryboardName LaunchScreen + NSCameraUsageDescription + Camera Permission UIMainStoryboardFile Main UISupportedInterfaceOrientations diff --git a/example/movinet/lib/main.dart b/example/movinet/lib/main.dart index 39cc2f5..bfe192b 100644 --- a/example/movinet/lib/main.dart +++ b/example/movinet/lib/main.dart @@ -160,7 +160,10 @@ class _MyHomePageState extends State with WidgetsBindingObserver { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Center(child: Text(widget.title)), + title: Image.asset( + 'assets/images/tfl_logo.png', + fit: BoxFit.contain, + ), backgroundColor: Colors.black.withOpacity(0.5), ), body: resultWidget(context), diff --git a/example/movinet/pubspec.yaml b/example/movinet/pubspec.yaml index 5b031ab..6a288ff 100644 --- a/example/movinet/pubspec.yaml +++ b/example/movinet/pubspec.yaml @@ -63,8 +63,9 @@ flutter: # To add assets to your application, add an assets section, like this: assets: - - assets/movinet_int8.tflite + - assets/ - assets/label/kinetics600_label_map.txt + - assets/images/tfl_logo.png # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware diff --git a/lib/src/interpreter.dart b/lib/src/interpreter.dart index a37ff00..bb6a8e2 100644 --- a/lib/src/interpreter.dart +++ b/lib/src/interpreter.dart @@ -212,10 +212,14 @@ class Interpreter { inputTensors.elementAt(i).setTo(inputs[i]); } - var inferenceStartNanos = DateTime.now().microsecondsSinceEpoch; + var inferenceStartNanos = DateTime + .now() + .microsecondsSinceEpoch; invoke(); _lastNativeInferenceDurationMicroSeconds = - DateTime.now().microsecondsSinceEpoch - inferenceStartNanos; + DateTime + .now() + .microsecondsSinceEpoch - inferenceStartNanos; } /// Gets all input tensors associated with the model. @@ -226,8 +230,9 @@ class Interpreter { var tensors = List.generate( tfliteBinding.TfLiteInterpreterGetInputTensorCount(_interpreter), - (i) => Tensor( - tfliteBinding.TfLiteInterpreterGetInputTensor(_interpreter, i)), + (i) => + Tensor( + tfliteBinding.TfLiteInterpreterGetInputTensor(_interpreter, i)), growable: false); return tensors; @@ -241,8 +246,10 @@ class Interpreter { var tensors = List.generate( tfliteBinding.TfLiteInterpreterGetOutputTensorCount(_interpreter), - (i) => Tensor( - tfliteBinding.TfLiteInterpreterGetOutputTensor(_interpreter, i)), + (i) => + Tensor( + tfliteBinding.TfLiteInterpreterGetOutputTensor( + _interpreter, i)), growable: false); return tensors; @@ -253,7 +260,7 @@ class Interpreter { final dimensionSize = shape.length; final dimensions = calloc(dimensionSize); final externalTypedData = - dimensions.cast().asTypedList(dimensionSize); + dimensions.cast().asTypedList(dimensionSize); externalTypedData.setRange(0, dimensionSize, shape); final status = tfliteBinding.TfLiteInterpreterResizeInputTensor( _interpreter, tensorIndex, dimensions, dimensionSize); @@ -341,7 +348,7 @@ class Interpreter { // check if signature key exists if (!_signatureRunners.containsKey(signatureKey)) { Pointer signatureKeyPointer = - signatureKey.toNativeUtf8() as Pointer; + signatureKey.toNativeUtf8() as Pointer; final signatureRunner = tfliteBinding.TfLiteInterpreterGetSignatureRunner( _interpreter, signatureKeyPointer); _signatureRunners[signatureKey] = signatureRunner; @@ -355,7 +362,7 @@ class Interpreter { int getSignatureInputCount(String signatureKey) { final signatureRunner = _getSignatureRunner(signatureKey); final subGraphIndex = - tfliteBinding.TfLiteSignatureRunnerGetInputCount(signatureRunner); + tfliteBinding.TfLiteSignatureRunnerGetInputCount(signatureRunner); return subGraphIndex; } @@ -363,7 +370,7 @@ class Interpreter { int getSignatureOutputCount(String signatureKey) { final signatureRunner = _getSignatureRunner(signatureKey); final subGraphIndex = - tfliteBinding.TfLiteSignatureRunnerGetOutputCount(signatureRunner); + tfliteBinding.TfLiteSignatureRunnerGetOutputCount(signatureRunner); return subGraphIndex; } @@ -371,7 +378,7 @@ class Interpreter { String getSignatureInputName(String signatureKey, int index) { final signatureRunner = _getSignatureRunner(signatureKey); final inputName = - tfliteBinding.TfLiteSignatureRunnerGetInputName(signatureRunner, index); + tfliteBinding.TfLiteSignatureRunnerGetInputName(signatureRunner, index); return inputName.cast().toDartString(); } @@ -383,8 +390,8 @@ class Interpreter { return outputName.cast().toDartString(); } - List getSignatureInputTensorShape( - String signatureKey, String inputName) { + List getSignatureInputTensorShape(String signatureKey, + String inputName) { final signatureRunner = _getSignatureRunner(signatureKey); final inputTensor = Tensor( tfliteBinding.TfLiteSignatureRunnerGetInputTensor( @@ -393,8 +400,8 @@ class Interpreter { return shape; } - List getSignatureOutputTensorShape( - String signatureKey, String outputName) { + List getSignatureOutputTensorShape(String signatureKey, + String outputName) { final signatureRunner = _getSignatureRunner(signatureKey); final outputTensor = Tensor( tfliteBinding.TfLiteSignatureRunnerGetOutputTensor( @@ -403,32 +410,6 @@ class Interpreter { return shape; } - /// get signature input tensor - Map getSignatureInputTensors( - String signatureKey, List keys) { - final signatureRunner = _getSignatureRunner(signatureKey); - Map tensors = HashMap(); - keys.forEach((key) { - tensors[key] = Tensor(tfliteBinding.TfLiteSignatureRunnerGetInputTensor( - signatureRunner, key.toNativeUtf8().cast())); - }); - - return tensors; - } - - /// get signature output tensor - Map getSignatureOutputTensors( - String signatureKey, List keys) { - final signatureRunner = _getSignatureRunner(signatureKey); - Map tensors = HashMap(); - keys.forEach((key) { - tensors[key] = Tensor(tfliteBinding.TfLiteSignatureRunnerGetOutputTensor( - signatureRunner, key.toNativeUtf8().cast())); - }); - - return tensors; - } - /// Run for single input and output void runSignature(Map inputs, Map outputs, String signatureKey) { @@ -440,21 +421,22 @@ class Interpreter { } final Pointer signatureRunner = - _getSignatureRunner(signatureKey); - - var inputTensor = - getSignatureInputTensors(signatureKey, inputs.keys.toList()); + _getSignatureRunner(signatureKey); inputs.forEach((key, value) { - inputTensor[key]?.setTo(value); + Tensor inputTensor = Tensor( + tfliteBinding.TfLiteSignatureRunnerGetInputTensor( + signatureRunner, key.toNativeUtf8().cast())); + inputTensor.setTo(value); }); tfliteBinding.TfLiteSignatureRunnerInvoke(signatureRunner); - var outputTensor = - getSignatureOutputTensors(signatureKey, outputs.keys.toList()); outputs.forEach((key, value) { - outputTensor[key]?.copyTo(value); + Tensor outputTensor = Tensor( + tfliteBinding.TfLiteSignatureRunnerGetOutputTensor( + signatureRunner, key.toNativeUtf8().cast())); + outputTensor.copyTo(value); }); }