├── README.md
├── TFlitedemo
├── .gitignore
├── .idea
│ ├── gradle.xml
│ ├── misc.xml
│ ├── modules.xml
│ └── runConfigurations.xml
├── README.md
├── app
│ ├── build.gradle
│ ├── libs
│ │ └── libtensorflowlite.jar
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── assets
│ │ ├── labels.txt
│ │ ├── labels_imagenet_slim.txt
│ │ ├── labels_mobilenet_quant_v1_224.txt
│ │ └── mobilenet_quant_v1_224.tflite
│ │ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── android
│ │ │ └── tflitecamerademo
│ │ │ ├── AutoFitTextureView.java
│ │ │ ├── Camera2BasicFragment.java
│ │ │ ├── CameraActivity.java
│ │ │ ├── ImageClassifier.java
│ │ │ ├── ImageClassifierFloatInception.java
│ │ │ └── ImageClassifierQuantizedMobileNet.java
│ │ ├── jnilibs
│ │ └── arm64-v8a
│ │ │ └── libtensorflowlite_jni.so
│ │ └── res
│ │ ├── drawable-hdpi
│ │ ├── ic_action_info.png
│ │ ├── ic_launcher.png
│ │ └── tile.9.png
│ │ ├── drawable-mdpi
│ │ ├── ic_action_info.png
│ │ └── ic_launcher.png
│ │ ├── drawable-xhdpi
│ │ ├── ic_action_info.png
│ │ └── ic_launcher.png
│ │ ├── drawable-xxhdpi
│ │ ├── ic_action_info.png
│ │ ├── ic_launcher.png
│ │ └── logo.png
│ │ ├── layout-land
│ │ └── fragment_camera2_basic.xml
│ │ ├── layout-v26
│ │ └── fragment_camera2_basic.xml
│ │ ├── layout
│ │ ├── activity_camera.xml
│ │ └── fragment_camera2_basic.xml
│ │ ├── values-sw600dp
│ │ ├── template-dimens.xml
│ │ └── template-styles.xml
│ │ ├── values-v11
│ │ └── template-styles.xml
│ │ ├── values-v21
│ │ ├── base-colors.xml
│ │ └── base-template-styles.xml
│ │ └── values
│ │ ├── base-strings.xml
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ ├── styles.xml
│ │ ├── template-dimens.xml
│ │ └── template-styles.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
└── TfLiteCameraDemo
├── .idea
├── gradle.xml
├── libraries
│ ├── junit_junit_4_12_jar.xml
│ └── org_hamcrest_hamcrest_core_1_3_jar.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── workspace.xml
├── TfLiteCameraDemo.iml
├── android.iml
├── app
├── app.iml
├── build.gradle
├── download-models.gradle
├── libs
│ └── libtensorflowlite.jar
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── assets
│ ├── box_priors.txt
│ ├── coco_labels_list.txt
│ ├── conv_actions_labels.txt
│ ├── download.sh
│ ├── labels.txt
│ ├── labels_list.txt
│ └── labels_mobilenet_quant_v1_224.txt
│ ├── java
│ └── org
│ │ └── tensorflow
│ │ └── demo
│ │ ├── AutoFitTextureView.java
│ │ ├── CameraActivity.java
│ │ ├── CameraConnectionFragment.java
│ │ ├── Classifier.java
│ │ ├── ClassifierActivity.java
│ │ ├── DetectorActivity.java
│ │ ├── LegacyCameraConnectionFragment.java
│ │ ├── OverlayView.java
│ │ ├── RecognitionScoreView.java
│ │ ├── RecognizeCommands.java
│ │ ├── ResultsView.java
│ │ ├── SpeechActivity.java
│ │ ├── TFLiteImageClassifier.java
│ │ ├── TFLiteObjectDetectionAPIModel.java
│ │ ├── env
│ │ ├── AssetUtils.java
│ │ ├── BorderedText.java
│ │ ├── ImageUtils.java
│ │ ├── Logger.java
│ │ ├── Size.java
│ │ └── SplitTimer.java
│ │ └── tracking
│ │ ├── MultiBoxTracker.java
│ │ └── ObjectTracker.java
│ ├── jnilibs
│ └── arm64-v8a
│ │ ├── libtensorflow_demo.so
│ │ └── libtensorflowlite_jni.so
│ └── res
│ ├── animator
│ └── color_animation.xml
│ ├── drawable-hdpi
│ ├── ic_action_info.png
│ ├── ic_launcher.png
│ └── tile.9.png
│ ├── drawable-mdpi
│ ├── ic_action_info.png
│ └── ic_launcher.png
│ ├── drawable-xhdpi
│ ├── ic_action_info.png
│ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ ├── ic_action_info.png
│ └── ic_launcher.png
│ ├── drawable
│ └── border.xml
│ ├── layout
│ ├── activity_camera.xml
│ ├── activity_speech.xml
│ ├── camera_connection_fragment.xml
│ ├── camera_connection_fragment_stylize.xml
│ ├── camera_connection_fragment_tracking.xml
│ └── list_text_item.xml
│ ├── values-sw600dp
│ ├── template-dimens.xml
│ └── template-styles.xml
│ ├── values-v11
│ ├── styles.xml
│ └── template-styles.xml
│ ├── values-v14
│ └── styles.xml
│ ├── values-v21
│ ├── base-colors.xml
│ └── base-template-styles.xml
│ └── values
│ ├── attrs.xml
│ ├── base-strings.xml
│ ├── colors.xml
│ ├── strings.xml
│ ├── styles.xml
│ ├── template-dimens.xml
│ └── template-styles.xml
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── local.properties
└── settings.gradle
/README.md:
--------------------------------------------------------------------------------
1 | # Tensorflow_Lite_Demo
2 | An example Android application using TensorFLow Lite is available on Tensorflow github, Creating a project directory in tensorflow/tensorflow/contrib/lite/ , which is builted on Android studio 3.0.I have download the model of tflite format and complie the libtensorflowlite_jni.so and libtensorflowlite.jar
3 |
4 |
5 | In the demo app, inference is done using the TensorFlow Lite Java API. The demo app classifies frames in real-time, displaying the top most probable classifications. It also displays the inference time taken to detect the object.
6 |
7 | # There are two ways to get the demo app to your device:
8 | 1,Use Android Studio to build the application. Here it's mine work !
9 | 2,Download the source code for TensorFlow Lite and the demo and build it using bazel.I have just give building commands !
10 |
11 |
12 | To build the demo app, run bazel:
13 | # TfLiteCameraDemo ---- The demo app classifier
14 | #./tensorflow direction run the bellow command
15 |
16 | bazel build --cxxopt=--std=c++11 //tensorflow/contrib/lite/java/demo/app/src/main:TfLiteCameraDemo
17 |
18 | for more infomation about [TfLiteCameraDemo](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/lite/java/demo)
19 |
20 | # tflite_demo ---- The demo app on classifier, detector, speech
21 | #./tensorflow direction run the bellow command
22 |
23 | sudo bazel build -c opt --config=android_arm{,64} --cxxopt='--std=c++11' "//tensorflow/contrib/lite/examples/android:tflite_demo"
24 |
25 | for more infomation about [tflite_demo](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/lite/examples/android/app)
26 |
27 | # bazel-bin/tensorflow/contrib/lite/java/libtensorflowlite.jar ---- the java api for tensorflow lite
28 |
29 | sudo bazel build -c opt --config=android_arm{,64} --cxxopt='--std=c++11' "//tensorflow/contrib/lite/java:tensorflowlite"
30 |
31 | # bazel-bin/tensorflow/examples/android/libtensorflow_demo.so ---- the native c++ jni interface for libtensorflowlite.jar
32 |
33 | sudo bazel build -c opt --config=android_arm{,64} --cxxopt='--std=c++11' "//tensorflow/examples/android:libtensorflow_demo.so"
34 |
35 |
36 | # attention
37 | 1, Edit your WORKSPACE to add SDK and NDK targets.
38 |
39 | android_sdk_repository(
40 | name = "androidsdk",
41 | api_level = 25,
42 | # Ensure that you have the build_tools_version below installed in the
43 | # SDK manager as it updates periodically.
44 | build_tools_version = "26.0.1",
45 | # Replace with path to Android SDK on your system
46 | path = "/home/XXXX/Software/SDK",
47 | )
48 |
49 | android_ndk_repository(
50 | name="androidndk",
51 | path="/home/XXXX/Software/NDK/android-ndk-r13b",
52 | # This needs to be 14 or higher to compile TensorFlow.
53 | # Please specify API level to >= 21 to build for 64-bit
54 | # archtectures or the Android NDK will automatically select biggest
55 | # API level that it supports without notice.
56 | # Note that the NDK version is not the API level.
57 | api_level=25)
58 |
59 |
60 | 2, Build this demo app with Bazel. The demo needs C++11. We configure the fat_apk_cpu flag to package support for 4 hardware variants. You may replace it with --config=android_arm64 on a 64-bit device and --config=android_arm for 32-bit device:
61 | For examples:
62 |
63 | bazel build -c opt --cxxopt='--std=c++11' --fat_apk_cpu=x86,x86_64,arm64-v8a,armeabi-v7a \
64 | //tensorflow/contrib/lite/examples/android:tflite_demo
65 |
66 |
67 | bazel build -c opt --config=android_arm{,64} --cxxopt='--std=c++11' "//tensorflow/contrib/lite/examples/android:tflite_demo"
68 |
69 | 3, Build the Tensorflow mobile demo using Bazel,which has a fuller set of supported functionality, while TensorFlow Lite supports only a limited set of operators, so not all models will work on it by default.
70 |
71 | #bazel-bin/tensorflow/examples/android/tensorflow_demo.apk
72 | bazel build -c opt //tensorflow/examples/android:tensorflow_demo
73 |
74 | #bazel-bin/tensorflow/contrib/android/libandroid_tensorflow_inference_java.jar
75 | bazel build //tensorflow/contrib/android:android_tensorflow_inference_java
76 |
77 | #bazel-bin/tensorflow/contrib/android/libtensorflow_inference.so
78 | sudo bazel build -c opt //tensorflow/contrib/android:libtensorflow_inference.so --crosstool_top=//external:android/crosstool --host_crosstool_top=@bazel_tools//tools/cpp:toolchain --cpu=armeabi-v7a --cxxopt='--std=c++11' --verbose_failures
79 | for more information about [Tensorflow Mobile] (https://www.tensorflow.org/mobile/android_build)
80 |
81 |
82 |
--------------------------------------------------------------------------------
/TFlitedemo/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/TFlitedemo/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
--------------------------------------------------------------------------------
/TFlitedemo/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/TFlitedemo/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/TFlitedemo/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/TFlitedemo/README.md:
--------------------------------------------------------------------------------
1 | # TF Lite Android App
2 |
3 | ## Building in Android Studio with TensorFlow Lite AAR from JCenter.
4 | The build.gradle is configured to use TensorFlow Lite's nightly build.
5 |
6 | If you see a build error related to compatibility with Tensorflow Lite's Java API (example: method X is
7 | undefined for type Interpreter), there has likely been a backwards compatible
8 | change to the API. You will need to pull new app code that's compatible with the
9 | nightly build and may need to first wait a few days for our external and internal
10 | code to merge.
11 |
12 | ## Building from Source with Bazel
13 |
14 | 1. Follow the [Bazel steps for the TF Demo App](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/android#bazel):
15 |
16 | 1. [Install Bazel and Android Prerequisites](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/android#install-bazel-and-android-prerequisites).
17 | It's easiest with Android Studio.
18 |
19 | - You'll need at least SDK version 23.
20 | - Make sure to install the latest version of Bazel. Some distributions
21 | ship with Bazel 0.5.4, which is too old.
22 | - Bazel requires Android Build Tools `26.0.1` or higher.
23 | - **Bazel is incompatible with NDK revisions 15 and above,** with revision
24 | 16 being a compile-breaking change. [Download an older version manually
25 | instead of using the SDK Manager.](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/android#install-bazel-and-android-prerequisites)
26 | - You also need to install the Android Support Repository, available
27 | through Android Studio under `Android SDK Manager -> SDK Tools ->
28 | Android Support Repository`.
29 |
30 | 2. [Edit your `WORKSPACE`](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/android#edit-workspace)
31 | to add SDK and NDK targets.
32 |
33 | NOTE: As long as you have the SDK and NDK installed, the `./configure`
34 | script will create these rules for you. Answer "Yes" when the script asks
35 | to automatically configure the `./WORKSPACE`.
36 |
37 | - Make sure the `api_level` in `WORKSPACE` is set to an SDK version that
38 | you have installed.
39 | - By default, Android Studio will install the SDK to `~/Android/Sdk` and
40 | the NDK to `~/Android/Sdk/ndk-bundle` (but the NDK should be a manual
41 | download until Bazel supports NDK 16. See bullet points under (1)).
42 |
43 | 2. Build the app with Bazel. The demo needs C++11:
44 |
45 | ```shell
46 | bazel build -c opt --cxxopt='--std=c++11' \
47 | //tensorflow/contrib/lite/java/demo/app/src/main:TfLiteCameraDemo
48 | ```
49 |
50 | 3. Install the demo on a
51 | [debug-enabled device](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/android#install):
52 |
53 | ```shell
54 | adb install bazel-bin/tensorflow/contrib/lite/java/demo/app/src/main/TfLiteCameraDemo.apk
55 | ```
56 |
--------------------------------------------------------------------------------
/TFlitedemo/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 26
5 | buildToolsVersion '26.0.2'
6 | defaultConfig {
7 | applicationId "android.example.com.tflitecamerademo"
8 | // Required by Camera2 API.
9 | minSdkVersion 21
10 | targetSdkVersion 26
11 | versionCode 1
12 | versionName "1.0"
13 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
14 |
15 |
16 | }
17 | lintOptions {
18 | abortOnError false
19 | }
20 | buildTypes {
21 | release {
22 | minifyEnabled false
23 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
24 | }
25 | }
26 | aaptOptions {
27 | noCompress "tflite"
28 | }
29 |
30 | compileOptions {
31 | sourceCompatibility JavaVersion.VERSION_1_8
32 | targetCompatibility JavaVersion.VERSION_1_8
33 | }
34 |
35 | sourceSets {
36 | main {
37 | // let gradle pack the shared library into apk
38 | jniLibs.srcDirs = ['src/main/jnilibs']
39 | }
40 | }
41 | }
42 |
43 | repositories {
44 | maven {
45 | url 'https://google.bintray.com/tensorflow'
46 | }
47 | }
48 |
49 | dependencies {
50 | compile fileTree(dir: 'libs', include: ['*.jar'])
51 |
52 | compile 'com.android.support:appcompat-v7:25.2.0'
53 | compile 'com.android.support.constraint:constraint-layout:1.0.2'
54 | compile 'com.android.support:design:25.2.0'
55 | compile 'com.android.support:support-annotations:25.3.1'
56 | compile 'com.android.support:support-v13:25.2.0'
57 |
58 | //compile 'org.tensorflow:tensorflow-lite:0.0.0-nightly'
59 |
60 | testCompile 'junit:junit:4.12'
61 | }
--------------------------------------------------------------------------------
/TFlitedemo/app/libs/libtensorflowlite.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TFlitedemo/app/libs/libtensorflowlite.jar
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
32 |
33 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/assets/mobilenet_quant_v1_224.tflite:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TFlitedemo/app/src/main/assets/mobilenet_quant_v1_224.tflite
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/java/com/example/android/tflitecamerademo/AutoFitTextureView.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 | ==============================================================================*/
15 |
16 | package com.example.android.tflitecamerademo;
17 |
18 | import android.content.Context;
19 | import android.util.AttributeSet;
20 | import android.view.TextureView;
21 |
22 | /** A {@link TextureView} that can be adjusted to a specified aspect ratio. */
23 | public class AutoFitTextureView extends TextureView {
24 |
25 | private int mRatioWidth = 0;
26 | private int mRatioHeight = 0;
27 |
28 | public AutoFitTextureView(Context context) {
29 | this(context, null);
30 | }
31 |
32 | public AutoFitTextureView(Context context, AttributeSet attrs) {
33 | this(context, attrs, 0);
34 | }
35 |
36 | public AutoFitTextureView(Context context, AttributeSet attrs, int defStyle) {
37 | super(context, attrs, defStyle);
38 | }
39 |
40 | /**
41 | * Sets the aspect ratio for this view. The size of the view will be measured based on the ratio
42 | * calculated from the parameters. Note that the actual sizes of parameters don't matter, that is,
43 | * calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.
44 | *
45 | * @param width Relative horizontal size
46 | * @param height Relative vertical size
47 | */
48 | public void setAspectRatio(int width, int height) {
49 | if (width < 0 || height < 0) {
50 | throw new IllegalArgumentException("Size cannot be negative.");
51 | }
52 | mRatioWidth = width;
53 | mRatioHeight = height;
54 | requestLayout();
55 | }
56 |
57 | @Override
58 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
59 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
60 | int width = MeasureSpec.getSize(widthMeasureSpec);
61 | int height = MeasureSpec.getSize(heightMeasureSpec);
62 | if (0 == mRatioWidth || 0 == mRatioHeight) {
63 | setMeasuredDimension(width, height);
64 | } else {
65 | if (width < height * mRatioWidth / mRatioHeight) {
66 | setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);
67 | } else {
68 | setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);
69 | }
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/java/com/example/android/tflitecamerademo/CameraActivity.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 | ==============================================================================*/
15 |
16 | package com.example.android.tflitecamerademo;
17 |
18 | import android.app.Activity;
19 | import android.os.Bundle;
20 |
21 | /** Main {@code Activity} class for the Camera app. */
22 | public class CameraActivity extends Activity {
23 |
24 | @Override
25 | protected void onCreate(Bundle savedInstanceState) {
26 | super.onCreate(savedInstanceState);
27 | setContentView(R.layout.activity_camera);
28 | if (null == savedInstanceState) {
29 | getFragmentManager()
30 | .beginTransaction()
31 | .replace(R.id.container, Camera2BasicFragment.newInstance())
32 | .commit();
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/java/com/example/android/tflitecamerademo/ImageClassifierFloatInception.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 | ==============================================================================*/
15 |
16 | package com.example.android.tflitecamerademo;
17 |
18 | import android.app.Activity;
19 |
20 | import java.io.IOException;
21 |
22 | /**
23 | * This classifier works with the Inception-v3 slim model.
24 | * It applies floating point inference rather than using a quantized model.
25 | */
26 | public class ImageClassifierFloatInception extends ImageClassifier {
27 |
28 | /**
29 | * The inception net requires additional normalization of the used input.
30 | */
31 | private static final int IMAGE_MEAN = 128;
32 | private static final float IMAGE_STD = 128.0f;
33 |
34 | /**
35 | * An array to hold inference results, to be feed into Tensorflow Lite as outputs.
36 | * This isn't part of the super class, because we need a primitive array here.
37 | */
38 | private float[][] labelProbArray = null;
39 |
40 | /**
41 | * Initializes an {@code ImageClassifier}.
42 | *
43 | * @param activity
44 | */
45 | ImageClassifierFloatInception(Activity activity) throws IOException {
46 | super(activity);
47 | labelProbArray = new float[1][getNumLabels()];
48 | }
49 |
50 | @Override
51 | protected String getModelPath() {
52 | // you can download this file from
53 | // https://storage.googleapis.com/download.tensorflow.org/models/tflite/inception_v3_slim_2016_android_2017_11_10.zip
54 | return "inceptionv3_slim_2016.tflite";
55 | }
56 |
57 | @Override
58 | protected String getLabelPath() {
59 | return "labels_imagenet_slim.txt";
60 | }
61 |
62 | @Override
63 | protected int getImageSizeX() {
64 | return 299;
65 | }
66 |
67 | @Override
68 | protected int getImageSizeY() {
69 | return 299;
70 | }
71 |
72 | @Override
73 | protected int getNumBytesPerChannel() {
74 | // a 32bit float value requires 4 bytes
75 | return 4;
76 | }
77 |
78 | @Override
79 | protected void addPixelValue(int pixelValue) {
80 | imgData.putFloat((((pixelValue >> 16) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
81 | imgData.putFloat((((pixelValue >> 8) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
82 | imgData.putFloat(((pixelValue & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
83 | }
84 |
85 | @Override
86 | protected float getProbability(int labelIndex) {
87 | return labelProbArray[0][labelIndex];
88 | }
89 |
90 | @Override
91 | protected void setProbability(int labelIndex, Number value) {
92 | labelProbArray[0][labelIndex] = value.floatValue();
93 | }
94 |
95 | @Override
96 | protected float getNormalizedProbability(int labelIndex) {
97 | // TODO the following value isn't in [0,1] yet, but may be greater. Why?
98 | return getProbability(labelIndex);
99 | }
100 |
101 | @Override
102 | protected void runInference() {
103 | tflite.run(imgData, labelProbArray);
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/java/com/example/android/tflitecamerademo/ImageClassifierQuantizedMobileNet.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 | ==============================================================================*/
15 |
16 | package com.example.android.tflitecamerademo;
17 |
18 | import android.app.Activity;
19 | import java.io.IOException;
20 |
21 | /**
22 | * This classifier works with the quantized MobileNet model.
23 | */
24 | public class ImageClassifierQuantizedMobileNet extends ImageClassifier {
25 |
26 | /**
27 | * An array to hold inference results, to be feed into Tensorflow Lite as outputs.
28 | * This isn't part of the super class, because we need a primitive array here.
29 | */
30 | private byte[][] labelProbArray = null;
31 |
32 | /**
33 | * Initializes an {@code ImageClassifier}.
34 | *
35 | * @param activity
36 | */
37 | ImageClassifierQuantizedMobileNet(Activity activity) throws IOException {
38 | super(activity);
39 | labelProbArray = new byte[1][getNumLabels()];
40 | }
41 |
42 | @Override
43 | protected String getModelPath() {
44 | // you can download this file from
45 | // https://storage.googleapis.com/download.tensorflow.org/models/tflite/mobilenet_v1_224_android_quant_2017_11_08.zip
46 | return "mobilenet_quant_v1_224.tflite";
47 | }
48 |
49 | @Override
50 | protected String getLabelPath() {
51 | return "labels_mobilenet_quant_v1_224.txt";
52 | }
53 |
54 | @Override
55 | protected int getImageSizeX() {
56 | return 224;
57 | }
58 |
59 | @Override
60 | protected int getImageSizeY() {
61 | return 224;
62 | }
63 |
64 | @Override
65 | protected int getNumBytesPerChannel() {
66 | // the quantized model uses a single byte only
67 | return 1;
68 | }
69 |
70 | @Override
71 | protected void addPixelValue(int pixelValue) {
72 | imgData.put((byte) ((pixelValue >> 16) & 0xFF));
73 | imgData.put((byte) ((pixelValue >> 8) & 0xFF));
74 | imgData.put((byte) (pixelValue & 0xFF));
75 | }
76 |
77 | @Override
78 | protected float getProbability(int labelIndex) {
79 | return labelProbArray[0][labelIndex];
80 | }
81 |
82 | @Override
83 | protected void setProbability(int labelIndex, Number value) {
84 | labelProbArray[0][labelIndex] = value.byteValue();
85 | }
86 |
87 | @Override
88 | protected float getNormalizedProbability(int labelIndex) {
89 | return (labelProbArray[0][labelIndex] & 0xff) / 255.0f;
90 | }
91 |
92 | @Override
93 | protected void runInference() {
94 | tflite.run(imgData, labelProbArray);
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/jnilibs/arm64-v8a/libtensorflowlite_jni.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TFlitedemo/app/src/main/jnilibs/arm64-v8a/libtensorflowlite_jni.so
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/drawable-hdpi/ic_action_info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TFlitedemo/app/src/main/res/drawable-hdpi/ic_action_info.png
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TFlitedemo/app/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/drawable-hdpi/tile.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TFlitedemo/app/src/main/res/drawable-hdpi/tile.9.png
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/drawable-mdpi/ic_action_info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TFlitedemo/app/src/main/res/drawable-mdpi/ic_action_info.png
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TFlitedemo/app/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/drawable-xhdpi/ic_action_info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TFlitedemo/app/src/main/res/drawable-xhdpi/ic_action_info.png
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TFlitedemo/app/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/drawable-xxhdpi/ic_action_info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TFlitedemo/app/src/main/res/drawable-xxhdpi/ic_action_info.png
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TFlitedemo/app/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/drawable-xxhdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TFlitedemo/app/src/main/res/drawable-xxhdpi/logo.png
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/layout-land/fragment_camera2_basic.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
23 |
24 |
29 |
30 |
35 |
36 |
42 |
43 |
49 |
55 |
56 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/layout-v26/fragment_camera2_basic.xml:
--------------------------------------------------------------------------------
1 |
16 |
21 |
22 |
27 |
28 |
38 |
39 |
46 |
47 |
58 |
59 |
60 |
69 |
76 |
83 |
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/layout/activity_camera.xml:
--------------------------------------------------------------------------------
1 |
16 |
23 |
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/layout/fragment_camera2_basic.xml:
--------------------------------------------------------------------------------
1 |
16 |
21 |
22 |
27 |
28 |
38 |
39 |
46 |
47 |
58 |
59 |
60 |
69 |
76 |
83 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/values-sw600dp/template-dimens.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 | @dimen/margin_huge
22 | @dimen/margin_medium
23 |
24 |
25 |
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/values-sw600dp/template-styles.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/values-v11/template-styles.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/values-v21/base-colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/values-v21/base-template-styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/values/base-strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 | TfLite Camera Demo
20 |
21 |
29 |
30 | Threads:
31 |
32 |
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | #cc4285f4
19 |
20 |
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 | Picture
18 | Info
19 | This sample needs camera permission.
20 | This device doesn\'t support Camera2 API.
21 | NN:On
22 | NN:Off
23 | Use NNAPI
24 | tflite
25 | NNAPI
26 |
27 |
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/values/template-dimens.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 | 4dp
22 | 8dp
23 | 16dp
24 | 32dp
25 | 64dp
26 |
27 |
28 |
29 | @dimen/margin_medium
30 | @dimen/margin_medium
31 |
32 |
33 |
--------------------------------------------------------------------------------
/TFlitedemo/app/src/main/res/values/template-styles.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
34 |
35 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/TFlitedemo/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:3.0.1'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
21 | task clean(type: Delete) {
22 | delete rootProject.buildDir
23 | }
24 |
--------------------------------------------------------------------------------
/TFlitedemo/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/TFlitedemo/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TFlitedemo/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/TFlitedemo/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Sep 28 09:01:41 PDT 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
7 |
--------------------------------------------------------------------------------
/TFlitedemo/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/TFlitedemo/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/TFlitedemo/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/.idea/libraries/junit_junit_4_12_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/.idea/libraries/org_hamcrest_hamcrest_core_1_3_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/TfLiteCameraDemo.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/android.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/app.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | generateDebugSources
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 26
5 | buildToolsVersion '26.0.2'
6 | defaultConfig {
7 | applicationId "org.tensorflow.lite.demo"
8 | minSdkVersion 21
9 | targetSdkVersion 26
10 | versionCode 1
11 | versionName "1.0"
12 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
13 |
14 | }
15 | lintOptions {
16 | abortOnError false
17 | }
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 | aaptOptions {
25 | noCompress "tflite"
26 | }
27 |
28 | compileOptions {
29 | sourceCompatibility JavaVersion.VERSION_1_8
30 | targetCompatibility JavaVersion.VERSION_1_8
31 | }
32 |
33 | sourceSets {
34 | main {
35 | // let gradle pack the shared library into apk
36 | jniLibs.srcDirs = ['src/main/jnilibs']
37 | }
38 | }
39 |
40 | }
41 |
42 | repositories {
43 | maven {
44 | url 'https://google.bintray.com/tensorflow'
45 | }
46 | }
47 |
48 | // import DownloadModels task
49 | project.ext.ASSET_DIR = projectDir.toString() + '/src/main/assets'
50 | project.ext.TMP_DIR = project.buildDir.toString() + '/downloads'
51 |
52 | // Download default models; if you wish to use your own models then
53 | // place them in the "assets" directory and comment out this line.
54 | //apply from: "download-models.gradle"
55 |
56 | dependencies {
57 | compile fileTree(dir: 'libs', include: ['*.jar'])
58 |
59 | //compile 'org.tensorflow:tensorflow-lite:0.0.0-nightly'
60 |
61 | testCompile 'junit:junit:4.12'
62 | }
63 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/download-models.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * download-models.gradle
3 | * Downloads model files from ${MODEL_URL} into application's asset folder
4 | * Input:
5 | * project.ext.TMP_DIR: absolute path to hold downloaded zip files
6 | * project.ext.ASSET_DIR: absolute path to save unzipped model files
7 | * Output:
8 | * 3 model files will be downloaded into given folder of ext.ASSET_DIR
9 | */
10 | // hard coded model files
11 | // LINT.IfChange
12 |
13 | def models = ['conv_actions_tflite.zip',
14 | 'mobilenet_ssd_tflite_v1.zip',
15 | 'mobilenet_v1_224_android_quant_2017_11_08.zip',
16 | 'coco_ssd_mobilenet_v1_1.0_quant_2018_06_29.zip']
17 | // LINT.ThenChange(//tensorflow/contrib/lite/examples/android/BUILD)
18 |
19 | // Root URL for model archives
20 | def MODEL_URL = 'https://storage.googleapis.com/download.tensorflow.org/models/tflite'
21 |
22 | buildscript {
23 | repositories {
24 | jcenter()
25 | }
26 | dependencies {
27 | classpath 'de.undercouch:gradle-download-task:3.2.0'
28 | }
29 | }
30 |
31 | import de.undercouch.gradle.tasks.download.Download
32 | task downloadFile(type: Download){
33 | for (f in models) {
34 | def modelUrl = MODEL_URL + "/" + f
35 | println "Downloading ${f} from ${modelUrl}"
36 | src modelUrl
37 | }
38 |
39 | dest new File(project.ext.TMP_DIR)
40 | overwrite true
41 | }
42 |
43 | task extractModels(type: Copy) {
44 | for (f in models) {
45 | def localFile = f.split("/")[-1]
46 | from zipTree(project.ext.TMP_DIR + '/' + localFile)
47 | }
48 |
49 | into file(project.ext.ASSET_DIR)
50 | fileMode 0644
51 | exclude '**/LICENSE'
52 |
53 | def needDownload = false
54 | for (f in models) {
55 | def localFile = f.split("/")[-1]
56 | if (!(new File(project.ext.TMP_DIR + '/' + localFile)).exists()) {
57 | needDownload = true
58 | }
59 | }
60 |
61 | if (needDownload) {
62 | dependsOn downloadFile
63 | }
64 | }
65 |
66 | tasks.whenTaskAdded { task ->
67 | if (task.name == 'assembleDebug') {
68 | task.dependsOn 'extractModels'
69 | }
70 | if (task.name == 'assembleRelease') {
71 | task.dependsOn 'extractModels'
72 | }
73 | }
74 |
75 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/libs/libtensorflowlite.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TfLiteCameraDemo/app/libs/libtensorflowlite.jar
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
30 |
31 |
36 |
37 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/assets/coco_labels_list.txt:
--------------------------------------------------------------------------------
1 | ???
2 | person
3 | bicycle
4 | car
5 | motorcycle
6 | airplane
7 | bus
8 | train
9 | truck
10 | boat
11 | traffic light
12 | fire hydrant
13 | ???
14 | stop sign
15 | parking meter
16 | bench
17 | bird
18 | cat
19 | dog
20 | horse
21 | sheep
22 | cow
23 | elephant
24 | bear
25 | zebra
26 | giraffe
27 | ???
28 | backpack
29 | umbrella
30 | ???
31 | ???
32 | handbag
33 | tie
34 | suitcase
35 | frisbee
36 | skis
37 | snowboard
38 | sports ball
39 | kite
40 | baseball bat
41 | baseball glove
42 | skateboard
43 | surfboard
44 | tennis racket
45 | bottle
46 | ???
47 | wine glass
48 | cup
49 | fork
50 | knife
51 | spoon
52 | bowl
53 | banana
54 | apple
55 | sandwich
56 | orange
57 | broccoli
58 | carrot
59 | hot dog
60 | pizza
61 | donut
62 | cake
63 | chair
64 | couch
65 | potted plant
66 | bed
67 | ???
68 | dining table
69 | ???
70 | ???
71 | toilet
72 | ???
73 | tv
74 | laptop
75 | mouse
76 | remote
77 | keyboard
78 | cell phone
79 | microwave
80 | oven
81 | toaster
82 | sink
83 | refrigerator
84 | ???
85 | book
86 | clock
87 | vase
88 | scissors
89 | teddy bear
90 | hair drier
91 | toothbrush
92 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/assets/conv_actions_labels.txt:
--------------------------------------------------------------------------------
1 | _silence_
2 | _unknown_
3 | yes
4 | no
5 | up
6 | down
7 | left
8 | right
9 | on
10 | off
11 | stop
12 | go
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/assets/download.sh:
--------------------------------------------------------------------------------
1 | wget https://storage.googleapis.com/download.tensorflow.org/models/tflite/conv_actions_tflite.zip
2 | wget https://storage.googleapis.com/download.tensorflow.org/models/tflite/mobilenet_ssd_tflite_v1.zip
3 | wget https://storage.googleapis.com/download.tensorflow.org/models/tflite/mobilenet_v1_224_android_quant_2017_11_08.zip
4 | wget https://storage.googleapis.com/download.tensorflow.org/models/tflite/coco_ssd_mobilenet_v1_1.0_quant_2018_06_29.zip
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/assets/labels_list.txt:
--------------------------------------------------------------------------------
1 | 0:background
2 | 1:hat
3 | 2:attention
4 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/java/org/tensorflow/demo/AutoFitTextureView.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 The TensorFlow Authors. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.tensorflow.demo;
18 |
19 | import android.content.Context;
20 | import android.util.AttributeSet;
21 | import android.view.TextureView;
22 |
23 | /**
24 | * A {@link TextureView} that can be adjusted to a specified aspect ratio.
25 | */
26 | public class AutoFitTextureView extends TextureView {
27 | private int ratioWidth = 0;
28 | private int ratioHeight = 0;
29 |
30 | public AutoFitTextureView(final Context context) {
31 | this(context, null);
32 | }
33 |
34 | public AutoFitTextureView(final Context context, final AttributeSet attrs) {
35 | this(context, attrs, 0);
36 | }
37 |
38 | public AutoFitTextureView(final Context context, final AttributeSet attrs, final int defStyle) {
39 | super(context, attrs, defStyle);
40 | }
41 |
42 | /**
43 | * Sets the aspect ratio for this view. The size of the view will be measured based on the ratio
44 | * calculated from the parameters. Note that the actual sizes of parameters don't matter, that
45 | * is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.
46 | *
47 | * @param width Relative horizontal size
48 | * @param height Relative vertical size
49 | */
50 | public void setAspectRatio(final int width, final int height) {
51 | if (width < 0 || height < 0) {
52 | throw new IllegalArgumentException("Size cannot be negative.");
53 | }
54 | ratioWidth = width;
55 | ratioHeight = height;
56 | requestLayout();
57 | }
58 |
59 | @Override
60 | protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
61 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
62 | final int width = MeasureSpec.getSize(widthMeasureSpec);
63 | final int height = MeasureSpec.getSize(heightMeasureSpec);
64 | if (0 == ratioWidth || 0 == ratioHeight) {
65 | setMeasuredDimension(width, height);
66 | } else {
67 | if (width < height * ratioWidth / ratioHeight) {
68 | setMeasuredDimension(width, width * ratioHeight / ratioWidth);
69 | } else {
70 | setMeasuredDimension(height * ratioWidth / ratioHeight, height);
71 | }
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/java/org/tensorflow/demo/Classifier.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 | ==============================================================================*/
15 |
16 | package org.tensorflow.demo;
17 |
18 | import android.graphics.Bitmap;
19 | import android.graphics.RectF;
20 | import java.util.List;
21 |
22 | /**
23 | * Generic interface for interacting with different recognition engines.
24 | */
25 | public interface Classifier {
26 | /**
27 | * An immutable result returned by a Classifier describing what was recognized.
28 | */
29 | public class Recognition {
30 | /**
31 | * A unique identifier for what has been recognized. Specific to the class, not the instance of
32 | * the object.
33 | */
34 | private final String id;
35 |
36 | /**
37 | * Display name for the recognition.
38 | */
39 | private final String title;
40 |
41 | /**
42 | * A sortable score for how good the recognition is relative to others. Higher should be better.
43 | */
44 | private final Float confidence;
45 |
46 | /** Optional location within the source image for the location of the recognized object. */
47 | private RectF location;
48 |
49 | public Recognition(
50 | final String id, final String title, final Float confidence, final RectF location) {
51 | this.id = id;
52 | this.title = title;
53 | this.confidence = confidence;
54 | this.location = location;
55 | }
56 |
57 | public String getId() {
58 | return id;
59 | }
60 |
61 | public String getTitle() {
62 | return title;
63 | }
64 |
65 | public Float getConfidence() {
66 | return confidence;
67 | }
68 |
69 | public RectF getLocation() {
70 | return new RectF(location);
71 | }
72 |
73 | public void setLocation(RectF location) {
74 | this.location = location;
75 | }
76 |
77 | @Override
78 | public String toString() {
79 | String resultString = "";
80 | if (id != null) {
81 | resultString += "[" + id + "] ";
82 | }
83 |
84 | if (title != null) {
85 | resultString += title + " ";
86 | }
87 |
88 | if (confidence != null) {
89 | resultString += String.format("(%.1f%%) ", confidence * 100.0f);
90 | }
91 |
92 | if (location != null) {
93 | resultString += location + " ";
94 | }
95 |
96 | return resultString.trim();
97 | }
98 | }
99 |
100 | List recognizeImage(Bitmap bitmap);
101 |
102 | void enableStatLogging(final boolean debug);
103 |
104 | String getStatString();
105 |
106 | void close();
107 | }
108 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/java/org/tensorflow/demo/ClassifierActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 The TensorFlow Authors. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.tensorflow.demo;
18 |
19 | import android.graphics.Bitmap;
20 | import android.graphics.Bitmap.Config;
21 | import android.graphics.Canvas;
22 | import android.graphics.Matrix;
23 | import android.graphics.Paint;
24 | import android.graphics.Typeface;
25 | import android.media.ImageReader.OnImageAvailableListener;
26 | import android.os.SystemClock;
27 | import android.util.Size;
28 | import android.util.TypedValue;
29 | import java.util.List;
30 | import java.util.Vector;
31 | import org.tensorflow.demo.OverlayView.DrawCallback;
32 | import org.tensorflow.demo.env.BorderedText;
33 | import org.tensorflow.demo.env.ImageUtils;
34 | import org.tensorflow.demo.env.Logger;
35 | import org.tensorflow.lite.demo.R; // Explicit import needed for internal Google builds.
36 |
37 | public class ClassifierActivity extends CameraActivity implements OnImageAvailableListener {
38 | private static final Logger LOGGER = new Logger();
39 |
40 | protected static final boolean SAVE_PREVIEW_BITMAP = false;
41 |
42 | private ResultsView resultsView;
43 |
44 | private Bitmap rgbFrameBitmap = null;
45 | private Bitmap croppedBitmap = null;
46 | private Bitmap cropCopyBitmap = null;
47 |
48 | private long lastProcessingTimeMs;
49 |
50 | // These are the settings for the original v1 Inception model. If you want to
51 | // use a model that's been produced from the TensorFlow for Poets codelab,
52 | // you'll need to set IMAGE_SIZE = 299, IMAGE_MEAN = 128, IMAGE_STD = 128,
53 | // INPUT_NAME = "Mul", and OUTPUT_NAME = "final_result".
54 | // You'll also need to update the MODEL_FILE and LABEL_FILE paths to point to
55 | // the ones you produced.
56 | //
57 | // To use v3 Inception model, strip the DecodeJpeg Op from your retrained
58 | // model first:
59 | //
60 | // python strip_unused.py \
61 | // --input_graph= \
62 | // --output_graph= \
63 | // --input_node_names="Mul" \
64 | // --output_node_names="final_result" \
65 | // --input_binary=true
66 | private static final int INPUT_SIZE = 224;
67 |
68 | private static final String MODEL_FILE = "mobilenet_quant_v1_224.tflite";
69 | private static final String LABEL_FILE = "labels_mobilenet_quant_v1_224.txt";
70 |
71 | private static final boolean MAINTAIN_ASPECT = true;
72 |
73 | private static final Size DESIRED_PREVIEW_SIZE = new Size(640, 480);
74 |
75 |
76 | private Integer sensorOrientation;
77 | private Classifier classifier;
78 | private Matrix frameToCropTransform;
79 | private Matrix cropToFrameTransform;
80 |
81 | private BorderedText borderedText;
82 |
83 | @Override
84 | protected int getLayoutId() {
85 | return R.layout.camera_connection_fragment;
86 | }
87 |
88 | @Override
89 | protected Size getDesiredPreviewFrameSize() {
90 | return DESIRED_PREVIEW_SIZE;
91 | }
92 |
93 | private static final float TEXT_SIZE_DIP = 10;
94 |
95 | @Override
96 | public void onPreviewSizeChosen(final Size size, final int rotation) {
97 | final float textSizePx = TypedValue.applyDimension(
98 | TypedValue.COMPLEX_UNIT_DIP, TEXT_SIZE_DIP, getResources().getDisplayMetrics());
99 | borderedText = new BorderedText(textSizePx);
100 | borderedText.setTypeface(Typeface.MONOSPACE);
101 |
102 | classifier = TFLiteImageClassifier.create(getAssets(), MODEL_FILE, LABEL_FILE, INPUT_SIZE);
103 |
104 | previewWidth = size.getWidth();
105 | previewHeight = size.getHeight();
106 |
107 | sensorOrientation = rotation - getScreenOrientation();
108 | LOGGER.i("Camera orientation relative to screen canvas: %d", sensorOrientation);
109 |
110 | LOGGER.i("Initializing at size %dx%d", previewWidth, previewHeight);
111 | rgbFrameBitmap = Bitmap.createBitmap(previewWidth, previewHeight, Config.ARGB_8888);
112 | croppedBitmap = Bitmap.createBitmap(INPUT_SIZE, INPUT_SIZE, Config.ARGB_8888);
113 |
114 | frameToCropTransform = ImageUtils.getTransformationMatrix(
115 | previewWidth, previewHeight,
116 | INPUT_SIZE, INPUT_SIZE,
117 | sensorOrientation, MAINTAIN_ASPECT);
118 |
119 | cropToFrameTransform = new Matrix();
120 | frameToCropTransform.invert(cropToFrameTransform);
121 |
122 | addCallback(
123 | new DrawCallback() {
124 | @Override
125 | public void drawCallback(final Canvas canvas) {
126 | renderDebug(canvas);
127 | }
128 | });
129 | }
130 |
131 | @Override
132 | protected void processImage() {
133 | rgbFrameBitmap.setPixels(getRgbBytes(), 0, previewWidth, 0, 0, previewWidth, previewHeight);
134 | final Canvas canvas = new Canvas(croppedBitmap);
135 | canvas.drawBitmap(rgbFrameBitmap, frameToCropTransform, null);
136 |
137 | // For examining the actual TF input.
138 | if (SAVE_PREVIEW_BITMAP) {
139 | ImageUtils.saveBitmap(croppedBitmap);
140 | }
141 | runInBackground(
142 | new Runnable() {
143 | @Override
144 | public void run() {
145 | final long startTime = SystemClock.uptimeMillis();
146 | final List results = classifier.recognizeImage(croppedBitmap);
147 | lastProcessingTimeMs = SystemClock.uptimeMillis() - startTime;
148 | LOGGER.i("Detect: %s", results);
149 | cropCopyBitmap = Bitmap.createBitmap(croppedBitmap);
150 | if (resultsView == null) {
151 | resultsView = (ResultsView) findViewById(R.id.results);
152 | }
153 | resultsView.setDuration(lastProcessingTimeMs);
154 | resultsView.setResults(results);
155 | requestRender();
156 | readyForNextImage();
157 | }
158 | });
159 | }
160 |
161 | @Override
162 | public void onSetDebug(boolean debug) {
163 | classifier.enableStatLogging(debug);
164 | }
165 |
166 | private void renderDebug(final Canvas canvas) {
167 | if (!isDebug()) {
168 | return;
169 | }
170 | final Bitmap copy = cropCopyBitmap;
171 | if (copy != null) {
172 | final Matrix matrix = new Matrix();
173 | final float scaleFactor = 2;
174 | matrix.postScale(scaleFactor, scaleFactor);
175 | matrix.postTranslate(
176 | canvas.getWidth() - copy.getWidth() * scaleFactor,
177 | canvas.getHeight() - copy.getHeight() * scaleFactor);
178 | canvas.drawBitmap(copy, matrix, new Paint());
179 |
180 | final Vector lines = new Vector();
181 | if (classifier != null) {
182 | String statString = classifier.getStatString();
183 | String[] statLines = statString.split("\n");
184 | for (String line : statLines) {
185 | lines.add(line);
186 | }
187 | }
188 |
189 | lines.add("Frame: " + previewWidth + "x" + previewHeight);
190 | lines.add("Crop: " + copy.getWidth() + "x" + copy.getHeight());
191 | lines.add("View: " + canvas.getWidth() + "x" + canvas.getHeight());
192 | lines.add("Rotation: " + sensorOrientation);
193 | lines.add("Inference time: " + lastProcessingTimeMs + "ms");
194 |
195 | borderedText.drawLines(canvas, 10, canvas.getHeight() - 10, lines);
196 | }
197 | }
198 | }
199 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/java/org/tensorflow/demo/DetectorActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 The TensorFlow Authors. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.tensorflow.demo;
18 |
19 | import android.graphics.Bitmap;
20 | import android.graphics.Bitmap.Config;
21 | import android.graphics.Canvas;
22 | import android.graphics.Color;
23 | import android.graphics.Matrix;
24 | import android.graphics.Paint;
25 | import android.graphics.Paint.Style;
26 | import android.graphics.RectF;
27 | import android.graphics.Typeface;
28 | import android.media.ImageReader.OnImageAvailableListener;
29 | import android.os.SystemClock;
30 | import android.util.Size;
31 | import android.util.TypedValue;
32 | import android.widget.Toast;
33 | import java.io.IOException;
34 | import java.util.LinkedList;
35 | import java.util.List;
36 | import java.util.Vector;
37 | import org.tensorflow.demo.OverlayView.DrawCallback;
38 | import org.tensorflow.demo.env.BorderedText;
39 | import org.tensorflow.demo.env.ImageUtils;
40 | import org.tensorflow.demo.env.Logger;
41 | import org.tensorflow.demo.tracking.MultiBoxTracker;
42 | import org.tensorflow.lite.demo.R; // Explicit import needed for internal Google builds.
43 |
44 | /**
45 | * An activity that uses a TensorFlowMultiBoxDetector and ObjectTracker to detect and then track
46 | * objects.
47 | */
48 | public class DetectorActivity extends CameraActivity implements OnImageAvailableListener {
49 | private static final Logger LOGGER = new Logger();
50 |
51 | // Configuration values for the prepackaged SSD model.
52 | private static final int TF_OD_API_INPUT_SIZE = 300;
53 | private static final boolean TF_OD_API_IS_QUANTIZED = false;
54 | private static final String TF_OD_API_MODEL_FILE = "detect.tflite";
55 | private static final String TF_OD_API_LABELS_FILE = "file:///android_asset/labels_list.txt";
56 |
57 | // Which detection model to use: by default uses Tensorflow Object Detection API frozen
58 | // checkpoints.
59 | private enum DetectorMode {
60 | TF_OD_API;
61 | }
62 |
63 | private static final DetectorMode MODE = DetectorMode.TF_OD_API;
64 |
65 | // Minimum detection confidence to track a detection.
66 | private static final float MINIMUM_CONFIDENCE_TF_OD_API = 0.6f;
67 |
68 | private static final boolean MAINTAIN_ASPECT = false;
69 |
70 | private static final Size DESIRED_PREVIEW_SIZE = new Size(640, 480);
71 |
72 | private static final boolean SAVE_PREVIEW_BITMAP = false;
73 | private static final float TEXT_SIZE_DIP = 10;
74 |
75 | private Integer sensorOrientation;
76 |
77 | private Classifier detector;
78 |
79 | private long lastProcessingTimeMs;
80 | private Bitmap rgbFrameBitmap = null;
81 | private Bitmap croppedBitmap = null;
82 | private Bitmap cropCopyBitmap = null;
83 |
84 | private boolean computingDetection = false;
85 |
86 | private long timestamp = 0;
87 |
88 | private Matrix frameToCropTransform;
89 | private Matrix cropToFrameTransform;
90 |
91 | private MultiBoxTracker tracker;
92 |
93 | private byte[] luminanceCopy;
94 |
95 | private BorderedText borderedText;
96 | @Override
97 | public void onPreviewSizeChosen(final Size size, final int rotation) {
98 | final float textSizePx =
99 | TypedValue.applyDimension(
100 | TypedValue.COMPLEX_UNIT_DIP, TEXT_SIZE_DIP, getResources().getDisplayMetrics());
101 | borderedText = new BorderedText(textSizePx);
102 | borderedText.setTypeface(Typeface.MONOSPACE);
103 |
104 | tracker = new MultiBoxTracker(this);
105 |
106 | int cropSize = TF_OD_API_INPUT_SIZE;
107 |
108 | try {
109 | detector =
110 | TFLiteObjectDetectionAPIModel.create(
111 | getAssets(),
112 | TF_OD_API_MODEL_FILE,
113 | TF_OD_API_LABELS_FILE,
114 | TF_OD_API_INPUT_SIZE,
115 | TF_OD_API_IS_QUANTIZED);
116 | cropSize = TF_OD_API_INPUT_SIZE;
117 | } catch (final IOException e) {
118 | LOGGER.e("Exception initializing classifier!", e);
119 | Toast toast =
120 | Toast.makeText(
121 | getApplicationContext(), "Classifier could not be initialized", Toast.LENGTH_SHORT);
122 | toast.show();
123 | finish();
124 | }
125 |
126 |
127 | previewWidth = size.getWidth();
128 | previewHeight = size.getHeight();
129 |
130 | sensorOrientation = rotation - getScreenOrientation();
131 | LOGGER.i("Camera orientation relative to screen canvas: %d", sensorOrientation);
132 |
133 | LOGGER.i("Initializing at size %dx%d", previewWidth, previewHeight);
134 | rgbFrameBitmap = Bitmap.createBitmap(previewWidth, previewHeight, Config.ARGB_8888);
135 | croppedBitmap = Bitmap.createBitmap(cropSize, cropSize, Config.ARGB_8888);
136 |
137 | frameToCropTransform =
138 | ImageUtils.getTransformationMatrix(
139 | previewWidth, previewHeight,
140 | cropSize, cropSize,
141 | sensorOrientation, MAINTAIN_ASPECT);
142 |
143 | cropToFrameTransform = new Matrix();
144 | frameToCropTransform.invert(cropToFrameTransform);
145 |
146 | trackingOverlay = (OverlayView) findViewById(R.id.tracking_overlay);
147 | trackingOverlay.addCallback(
148 | new DrawCallback() {
149 | @Override
150 | public void drawCallback(final Canvas canvas) {
151 | tracker.draw(canvas);
152 | if (isDebug()) {
153 | tracker.drawDebug(canvas);
154 | }
155 | }
156 | });
157 |
158 | addCallback(
159 | new DrawCallback() {
160 | @Override
161 | public void drawCallback(final Canvas canvas) {
162 | if (!isDebug()) {
163 | return;
164 | }
165 | final Bitmap copy = cropCopyBitmap;
166 | if (copy == null) {
167 | return;
168 | }
169 |
170 | final int backgroundColor = Color.argb(100, 0, 0, 0);
171 | canvas.drawColor(backgroundColor);
172 |
173 | final Matrix matrix = new Matrix();
174 | final float scaleFactor = 2;
175 | matrix.postScale(scaleFactor, scaleFactor);
176 | matrix.postTranslate(
177 | canvas.getWidth() - copy.getWidth() * scaleFactor,
178 | canvas.getHeight() - copy.getHeight() * scaleFactor);
179 | canvas.drawBitmap(copy, matrix, new Paint());
180 |
181 | final Vector lines = new Vector();
182 | if (detector != null) {
183 | final String statString = detector.getStatString();
184 | final String[] statLines = statString.split("\n");
185 | for (final String line : statLines) {
186 | lines.add(line);
187 | }
188 | }
189 | lines.add("");
190 |
191 | lines.add("Frame: " + previewWidth + "x" + previewHeight);
192 | lines.add("Crop: " + copy.getWidth() + "x" + copy.getHeight());
193 | lines.add("View: " + canvas.getWidth() + "x" + canvas.getHeight());
194 | lines.add("Rotation: " + sensorOrientation);
195 | lines.add("Inference time: " + lastProcessingTimeMs + "ms");
196 |
197 | borderedText.drawLines(canvas, 10, canvas.getHeight() - 10, lines);
198 | }
199 | });
200 | }
201 |
202 | OverlayView trackingOverlay;
203 |
204 | @Override
205 | protected void processImage() {
206 | ++timestamp;
207 | final long currTimestamp = timestamp;
208 | byte[] originalLuminance = getLuminance();
209 | tracker.onFrame(
210 | previewWidth,
211 | previewHeight,
212 | getLuminanceStride(),
213 | sensorOrientation,
214 | originalLuminance,
215 | timestamp);
216 | trackingOverlay.postInvalidate();
217 |
218 | // No mutex needed as this method is not reentrant.
219 | if (computingDetection) {
220 | readyForNextImage();
221 | return;
222 | }
223 | computingDetection = true;
224 | LOGGER.i("Preparing image " + currTimestamp + " for detection in bg thread.");
225 |
226 | rgbFrameBitmap.setPixels(getRgbBytes(), 0, previewWidth, 0, 0, previewWidth, previewHeight);
227 |
228 | if (luminanceCopy == null) {
229 | luminanceCopy = new byte[originalLuminance.length];
230 | }
231 | System.arraycopy(originalLuminance, 0, luminanceCopy, 0, originalLuminance.length);
232 | readyForNextImage();
233 |
234 | final Canvas canvas = new Canvas(croppedBitmap);
235 | canvas.drawBitmap(rgbFrameBitmap, frameToCropTransform, null);
236 | // For examining the actual TF input.
237 | if (SAVE_PREVIEW_BITMAP) {
238 | ImageUtils.saveBitmap(croppedBitmap);
239 | }
240 |
241 | runInBackground(
242 | new Runnable() {
243 | @Override
244 | public void run() {
245 | LOGGER.i("Running detection on image " + currTimestamp);
246 | final long startTime = SystemClock.uptimeMillis();
247 | final List results = detector.recognizeImage(croppedBitmap);
248 | lastProcessingTimeMs = SystemClock.uptimeMillis() - startTime;
249 |
250 | cropCopyBitmap = Bitmap.createBitmap(croppedBitmap);
251 | final Canvas canvas = new Canvas(cropCopyBitmap);
252 | final Paint paint = new Paint();
253 | paint.setColor(Color.RED);
254 | paint.setStyle(Style.STROKE);
255 | paint.setStrokeWidth(2.0f);
256 |
257 | float minimumConfidence = MINIMUM_CONFIDENCE_TF_OD_API;
258 | switch (MODE) {
259 | case TF_OD_API:
260 | minimumConfidence = MINIMUM_CONFIDENCE_TF_OD_API;
261 | break;
262 | }
263 |
264 | final List mappedRecognitions =
265 | new LinkedList();
266 |
267 | for (final Classifier.Recognition result : results) {
268 | final RectF location = result.getLocation();
269 | if (location != null && result.getConfidence() >= minimumConfidence) {
270 | canvas.drawRect(location, paint);
271 |
272 | cropToFrameTransform.mapRect(location);
273 | result.setLocation(location);
274 | mappedRecognitions.add(result);
275 | }
276 | }
277 |
278 | tracker.trackResults(mappedRecognitions, luminanceCopy, currTimestamp);
279 | trackingOverlay.postInvalidate();
280 |
281 | requestRender();
282 | computingDetection = false;
283 | }
284 | });
285 | }
286 |
287 | @Override
288 | protected int getLayoutId() {
289 | return R.layout.camera_connection_fragment_tracking;
290 | }
291 |
292 | @Override
293 | protected Size getDesiredPreviewFrameSize() {
294 | return DESIRED_PREVIEW_SIZE;
295 | }
296 |
297 | @Override
298 | public void onSetDebug(final boolean debug) {
299 | detector.enableStatLogging(debug);
300 | }
301 | }
302 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/java/org/tensorflow/demo/LegacyCameraConnectionFragment.java:
--------------------------------------------------------------------------------
1 | package org.tensorflow.demo;
2 |
3 | /*
4 | * Copyright 2017 The TensorFlow Authors. All Rights Reserved.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.app.Fragment;
20 | import android.graphics.SurfaceTexture;
21 | import android.hardware.Camera;
22 | import android.hardware.Camera.CameraInfo;
23 | import android.os.Bundle;
24 | import android.os.Handler;
25 | import android.os.HandlerThread;
26 | import android.util.Size;
27 | import android.util.SparseIntArray;
28 | import android.view.LayoutInflater;
29 | import android.view.Surface;
30 | import android.view.TextureView;
31 | import android.view.View;
32 | import android.view.ViewGroup;
33 | import java.io.IOException;
34 | import java.util.List;
35 | import org.tensorflow.demo.env.ImageUtils;
36 | import org.tensorflow.demo.env.Logger;
37 | import org.tensorflow.lite.demo.R; // Explicit import needed for internal Google builds.
38 |
39 | public class LegacyCameraConnectionFragment extends Fragment {
40 | private Camera camera;
41 | private static final Logger LOGGER = new Logger();
42 | private Camera.PreviewCallback imageListener;
43 | private Size desiredSize;
44 |
45 | /**
46 | * The layout identifier to inflate for this Fragment.
47 | */
48 | private int layout;
49 |
50 | public LegacyCameraConnectionFragment(
51 | final Camera.PreviewCallback imageListener, final int layout, final Size desiredSize) {
52 | this.imageListener = imageListener;
53 | this.layout = layout;
54 | this.desiredSize = desiredSize;
55 | }
56 |
57 | /**
58 | * Conversion from screen rotation to JPEG orientation.
59 | */
60 | private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
61 |
62 | static {
63 | ORIENTATIONS.append(Surface.ROTATION_0, 90);
64 | ORIENTATIONS.append(Surface.ROTATION_90, 0);
65 | ORIENTATIONS.append(Surface.ROTATION_180, 270);
66 | ORIENTATIONS.append(Surface.ROTATION_270, 180);
67 | }
68 |
69 | /**
70 | * {@link android.view.TextureView.SurfaceTextureListener} handles several lifecycle events on a
71 | * {@link TextureView}.
72 | */
73 | private final TextureView.SurfaceTextureListener surfaceTextureListener =
74 | new TextureView.SurfaceTextureListener() {
75 | @Override
76 | public void onSurfaceTextureAvailable(
77 | final SurfaceTexture texture, final int width, final int height) {
78 |
79 | int index = getCameraId();
80 | camera = Camera.open(index);
81 |
82 | try {
83 | Camera.Parameters parameters = camera.getParameters();
84 | List focusModes = parameters.getSupportedFocusModes();
85 | if (focusModes != null
86 | && focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
87 | parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
88 | }
89 | List cameraSizes = parameters.getSupportedPreviewSizes();
90 | Size[] sizes = new Size[cameraSizes.size()];
91 | int i = 0;
92 | for (Camera.Size size : cameraSizes) {
93 | sizes[i++] = new Size(size.width, size.height);
94 | }
95 | Size previewSize =
96 | CameraConnectionFragment.chooseOptimalSize(
97 | sizes, desiredSize.getWidth(), desiredSize.getHeight());
98 | parameters.setPreviewSize(previewSize.getWidth(), previewSize.getHeight());
99 | camera.setDisplayOrientation(90);
100 | camera.setParameters(parameters);
101 | camera.setPreviewTexture(texture);
102 | } catch (IOException exception) {
103 | camera.release();
104 | }
105 |
106 | camera.setPreviewCallbackWithBuffer(imageListener);
107 | Camera.Size s = camera.getParameters().getPreviewSize();
108 | camera.addCallbackBuffer(new byte[ImageUtils.getYUVByteSize(s.height, s.width)]);
109 |
110 | textureView.setAspectRatio(s.height, s.width);
111 |
112 | camera.startPreview();
113 | }
114 |
115 | @Override
116 | public void onSurfaceTextureSizeChanged(
117 | final SurfaceTexture texture, final int width, final int height) {}
118 |
119 | @Override
120 | public boolean onSurfaceTextureDestroyed(final SurfaceTexture texture) {
121 | return true;
122 | }
123 |
124 | @Override
125 | public void onSurfaceTextureUpdated(final SurfaceTexture texture) {}
126 | };
127 |
128 | /**
129 | * An {@link AutoFitTextureView} for camera preview.
130 | */
131 | private AutoFitTextureView textureView;
132 |
133 | /**
134 | * An additional thread for running tasks that shouldn't block the UI.
135 | */
136 | private HandlerThread backgroundThread;
137 |
138 | @Override
139 | public View onCreateView(
140 | final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
141 | return inflater.inflate(layout, container, false);
142 | }
143 |
144 | @Override
145 | public void onViewCreated(final View view, final Bundle savedInstanceState) {
146 | textureView = (AutoFitTextureView) view.findViewById(R.id.texture);
147 | }
148 |
149 | @Override
150 | public void onActivityCreated(final Bundle savedInstanceState) {
151 | super.onActivityCreated(savedInstanceState);
152 | }
153 |
154 | @Override
155 | public void onResume() {
156 | super.onResume();
157 | startBackgroundThread();
158 | // When the screen is turned off and turned back on, the SurfaceTexture is already
159 | // available, and "onSurfaceTextureAvailable" will not be called. In that case, we can open
160 | // a camera and start preview from here (otherwise, we wait until the surface is ready in
161 | // the SurfaceTextureListener).
162 |
163 | if (textureView.isAvailable()) {
164 | camera.startPreview();
165 | } else {
166 | textureView.setSurfaceTextureListener(surfaceTextureListener);
167 | }
168 | }
169 |
170 | @Override
171 | public void onPause() {
172 | stopCamera();
173 | stopBackgroundThread();
174 | super.onPause();
175 | }
176 |
177 | /**
178 | * Starts a background thread and its {@link Handler}.
179 | */
180 | private void startBackgroundThread() {
181 | backgroundThread = new HandlerThread("CameraBackground");
182 | backgroundThread.start();
183 | }
184 |
185 | /**
186 | * Stops the background thread and its {@link Handler}.
187 | */
188 | private void stopBackgroundThread() {
189 | backgroundThread.quitSafely();
190 | try {
191 | backgroundThread.join();
192 | backgroundThread = null;
193 | } catch (final InterruptedException e) {
194 | LOGGER.e(e, "Exception!");
195 | }
196 | }
197 |
198 | protected void stopCamera() {
199 | if (camera != null) {
200 | camera.stopPreview();
201 | camera.setPreviewCallback(null);
202 | camera.release();
203 | camera = null;
204 | }
205 | }
206 |
207 | private int getCameraId() {
208 | CameraInfo ci = new CameraInfo();
209 | for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
210 | Camera.getCameraInfo(i, ci);
211 | if (ci.facing == CameraInfo.CAMERA_FACING_BACK)
212 | return i;
213 | }
214 | return -1; // No camera found
215 | }
216 | }
217 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/java/org/tensorflow/demo/OverlayView.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2016 The TensorFlow Authors. All Rights Reserved.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 | ==============================================================================*/
15 |
16 | package org.tensorflow.demo;
17 |
18 | import android.content.Context;
19 | import android.graphics.Canvas;
20 | import android.util.AttributeSet;
21 | import android.view.View;
22 | import java.util.LinkedList;
23 | import java.util.List;
24 |
25 | /**
26 | * A simple View providing a render callback to other classes.
27 | */
28 | public class OverlayView extends View {
29 | private final List callbacks = new LinkedList();
30 |
31 | public OverlayView(final Context context, final AttributeSet attrs) {
32 | super(context, attrs);
33 | }
34 |
35 | /**
36 | * Interface defining the callback for client classes.
37 | */
38 | public interface DrawCallback {
39 | public void drawCallback(final Canvas canvas);
40 | }
41 |
42 | public void addCallback(final DrawCallback callback) {
43 | callbacks.add(callback);
44 | }
45 |
46 | @Override
47 | public synchronized void draw(final Canvas canvas) {
48 | for (final DrawCallback callback : callbacks) {
49 | callback.drawCallback(canvas);
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/java/org/tensorflow/demo/RecognitionScoreView.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 | ==============================================================================*/
15 |
16 | package org.tensorflow.demo;
17 |
18 | import android.content.Context;
19 | import android.graphics.Canvas;
20 | import android.graphics.Paint;
21 | import android.util.AttributeSet;
22 | import android.util.TypedValue;
23 | import android.view.View;
24 | import java.util.List;
25 | import org.tensorflow.demo.Classifier.Recognition;
26 |
27 | public class RecognitionScoreView extends View implements ResultsView {
28 | private static final float TEXT_SIZE_DIP = 24;
29 | private List results;
30 | private final float textSizePx;
31 | private final Paint fgPaint;
32 | private final Paint bgPaint;
33 | private long duration;
34 |
35 | public RecognitionScoreView(final Context context, final AttributeSet set) {
36 | super(context, set);
37 |
38 | textSizePx =
39 | TypedValue.applyDimension(
40 | TypedValue.COMPLEX_UNIT_DIP, TEXT_SIZE_DIP, getResources().getDisplayMetrics());
41 | fgPaint = new Paint();
42 | fgPaint.setTextSize(textSizePx);
43 |
44 | bgPaint = new Paint();
45 | bgPaint.setColor(0xcc4285f4);
46 | }
47 |
48 | @Override
49 | public void setResults(final List results) {
50 | this.results = results;
51 | postInvalidate();
52 | }
53 |
54 | @Override
55 | public void setDuration(long duration) {
56 | this.duration = duration;
57 | }
58 |
59 | @Override
60 | public void onDraw(final Canvas canvas) {
61 | final int x = 10;
62 | int y = (int) (fgPaint.getTextSize() * 1.5f);
63 |
64 | canvas.drawPaint(bgPaint);
65 |
66 | if (results != null) {
67 | canvas.drawText("Inference time:"+duration + " ms", x, y, fgPaint);
68 | y += fgPaint.getTextSize() * 1.5f;
69 | for (final Recognition recog : results) {
70 | canvas.drawText(recog.getTitle() + ": " + recog.getConfidence(), x, y, fgPaint);
71 | y += (int) (fgPaint.getTextSize() * 1.5f);
72 | }
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/java/org/tensorflow/demo/RecognizeCommands.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 The TensorFlow Authors. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.tensorflow.demo;
18 |
19 | import android.util.Log;
20 | import android.util.Pair;
21 | import java.util.ArrayDeque;
22 | import java.util.ArrayList;
23 | import java.util.Arrays;
24 | import java.util.Deque;
25 | import java.util.List;
26 |
27 | /** Reads in results from an instantaneous audio recognition model and smoothes them over time. */
28 | public class RecognizeCommands {
29 | // Configuration settings.
30 | private List labels = new ArrayList();
31 | private long averageWindowDurationMs;
32 | private float detectionThreshold;
33 | private int suppressionMs;
34 | private int minimumCount;
35 | private long minimumTimeBetweenSamplesMs;
36 |
37 | // Working variables.
38 | private Deque> previousResults = new ArrayDeque>();
39 | private String previousTopLabel;
40 | private int labelsCount;
41 | private long previousTopLabelTime;
42 | private float previousTopLabelScore;
43 |
44 | private static final String SILENCE_LABEL = "_silence_";
45 | private static final long MINIMUM_TIME_FRACTION = 4;
46 |
47 | public RecognizeCommands(
48 | List inLabels,
49 | long inAverageWindowDurationMs,
50 | float inDetectionThreshold,
51 | int inSuppressionMS,
52 | int inMinimumCount,
53 | long inMinimumTimeBetweenSamplesMS) {
54 | labels = inLabels;
55 | averageWindowDurationMs = inAverageWindowDurationMs;
56 | detectionThreshold = inDetectionThreshold;
57 | suppressionMs = inSuppressionMS;
58 | minimumCount = inMinimumCount;
59 | labelsCount = inLabels.size();
60 | previousTopLabel = SILENCE_LABEL;
61 | previousTopLabelTime = Long.MIN_VALUE;
62 | previousTopLabelScore = 0.0f;
63 | minimumTimeBetweenSamplesMs = inMinimumTimeBetweenSamplesMS;
64 | }
65 |
66 | /** Holds information about what's been recognized. */
67 | public static class RecognitionResult {
68 | public final String foundCommand;
69 | public final float score;
70 | public final boolean isNewCommand;
71 |
72 | public RecognitionResult(String inFoundCommand, float inScore, boolean inIsNewCommand) {
73 | foundCommand = inFoundCommand;
74 | score = inScore;
75 | isNewCommand = inIsNewCommand;
76 | }
77 | }
78 |
79 | private static class ScoreForSorting implements Comparable {
80 | public final float score;
81 | public final int index;
82 |
83 | public ScoreForSorting(float inScore, int inIndex) {
84 | score = inScore;
85 | index = inIndex;
86 | }
87 |
88 | @Override
89 | public int compareTo(ScoreForSorting other) {
90 | if (this.score > other.score) {
91 | return -1;
92 | } else if (this.score < other.score) {
93 | return 1;
94 | } else {
95 | return 0;
96 | }
97 | }
98 | }
99 |
100 | public RecognitionResult processLatestResults(float[] currentResults, long currentTimeMS) {
101 | if (currentResults.length != labelsCount) {
102 | throw new RuntimeException(
103 | "The results for recognition should contain "
104 | + labelsCount
105 | + " elements, but there are "
106 | + currentResults.length);
107 | }
108 |
109 | if ((!previousResults.isEmpty()) && (currentTimeMS < previousResults.getFirst().first)) {
110 | throw new RuntimeException(
111 | "You must feed results in increasing time order, but received a timestamp of "
112 | + currentTimeMS
113 | + " that was earlier than the previous one of "
114 | + previousResults.getFirst().first);
115 | }
116 |
117 | final int howManyResults = previousResults.size();
118 | // Ignore any results that are coming in too frequently.
119 | if (howManyResults > 1) {
120 | final long timeSinceMostRecent = currentTimeMS - previousResults.getLast().first;
121 | if (timeSinceMostRecent < minimumTimeBetweenSamplesMs) {
122 | return new RecognitionResult(previousTopLabel, previousTopLabelScore, false);
123 | }
124 | }
125 |
126 | // Add the latest results to the head of the queue.
127 | previousResults.addLast(new Pair(currentTimeMS, currentResults));
128 |
129 | // Prune any earlier results that are too old for the averaging window.
130 | final long timeLimit = currentTimeMS - averageWindowDurationMs;
131 | while (previousResults.getFirst().first < timeLimit) {
132 | previousResults.removeFirst();
133 | }
134 |
135 | // If there are too few results, assume the result will be unreliable and
136 | // bail.
137 | final long earliestTime = previousResults.getFirst().first;
138 | final long samplesDuration = currentTimeMS - earliestTime;
139 | if ((howManyResults < minimumCount)
140 | || (samplesDuration < (averageWindowDurationMs / MINIMUM_TIME_FRACTION))) {
141 | Log.v("RecognizeResult", "Too few results");
142 | return new RecognitionResult(previousTopLabel, 0.0f, false);
143 | }
144 |
145 | // Calculate the average score across all the results in the window.
146 | float[] averageScores = new float[labelsCount];
147 | for (Pair previousResult : previousResults) {
148 | final float[] scoresTensor = previousResult.second;
149 | int i = 0;
150 | while (i < scoresTensor.length) {
151 | averageScores[i] += scoresTensor[i] / howManyResults;
152 | ++i;
153 | }
154 | }
155 |
156 | // Sort the averaged results in descending score order.
157 | ScoreForSorting[] sortedAverageScores = new ScoreForSorting[labelsCount];
158 | for (int i = 0; i < labelsCount; ++i) {
159 | sortedAverageScores[i] = new ScoreForSorting(averageScores[i], i);
160 | }
161 | Arrays.sort(sortedAverageScores);
162 |
163 | // See if the latest top score is enough to trigger a detection.
164 | final int currentTopIndex = sortedAverageScores[0].index;
165 | final String currentTopLabel = labels.get(currentTopIndex);
166 | final float currentTopScore = sortedAverageScores[0].score;
167 | // If we've recently had another label trigger, assume one that occurs too
168 | // soon afterwards is a bad result.
169 | long timeSinceLastTop;
170 | if (previousTopLabel.equals(SILENCE_LABEL) || (previousTopLabelTime == Long.MIN_VALUE)) {
171 | timeSinceLastTop = Long.MAX_VALUE;
172 | } else {
173 | timeSinceLastTop = currentTimeMS - previousTopLabelTime;
174 | }
175 | boolean isNewCommand;
176 | if ((currentTopScore > detectionThreshold) && (timeSinceLastTop > suppressionMs)) {
177 | previousTopLabel = currentTopLabel;
178 | previousTopLabelTime = currentTimeMS;
179 | previousTopLabelScore = currentTopScore;
180 | isNewCommand = true;
181 | } else {
182 | isNewCommand = false;
183 | }
184 | return new RecognitionResult(currentTopLabel, currentTopScore, isNewCommand);
185 | }
186 | }
187 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/java/org/tensorflow/demo/ResultsView.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2016 The TensorFlow Authors. All Rights Reserved.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 | ==============================================================================*/
15 |
16 | package org.tensorflow.demo;
17 |
18 | import java.util.List;
19 | import org.tensorflow.demo.Classifier.Recognition;
20 |
21 | public interface ResultsView {
22 | public void setResults(final List results);
23 | public void setDuration(final long duration);
24 | }
25 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/java/org/tensorflow/demo/TFLiteImageClassifier.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2016 The TensorFlow Authors. All Rights Reserved.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 | ==============================================================================*/
15 |
16 | package org.tensorflow.demo;
17 |
18 | import android.content.res.AssetFileDescriptor;
19 | import android.content.res.AssetManager;
20 | import android.graphics.Bitmap;
21 | import android.os.SystemClock;
22 | import android.os.Trace;
23 | import android.util.Log;
24 | import java.io.BufferedReader;
25 | import java.io.FileInputStream;
26 | import java.io.IOException;
27 | import java.io.InputStreamReader;
28 | import java.nio.ByteBuffer;
29 | import java.nio.ByteOrder;
30 | import java.nio.MappedByteBuffer;
31 | import java.nio.channels.FileChannel;
32 | import java.util.ArrayList;
33 | import java.util.Comparator;
34 | import java.util.List;
35 | import java.util.PriorityQueue;
36 | import java.util.Vector;
37 | import org.tensorflow.lite.Interpreter;
38 |
39 | /** A classifier specialized to label images using TensorFlow. */
40 | public class TFLiteImageClassifier implements Classifier {
41 | private static final String TAG = "TFLiteImageClassifier";
42 |
43 | // Only return this many results with at least this confidence.
44 | private static final int MAX_RESULTS = 3;
45 |
46 | private Interpreter tfLite;
47 |
48 | /** Dimensions of inputs. */
49 | private static final int DIM_BATCH_SIZE = 1;
50 |
51 | private static final int DIM_PIXEL_SIZE = 3;
52 |
53 | private static final int DIM_IMG_SIZE_X = 224;
54 | private static final int DIM_IMG_SIZE_Y = 224;
55 |
56 | byte[][] labelProb;
57 |
58 | // Pre-allocated buffers.
59 | private Vector labels = new Vector();
60 | private int[] intValues;
61 | private ByteBuffer imgData = null;
62 |
63 | private TFLiteImageClassifier() {}
64 |
65 | /** Memory-map the model file in Assets. */
66 | private static MappedByteBuffer loadModelFile(AssetManager assets, String modelFilename)
67 | throws IOException {
68 | AssetFileDescriptor fileDescriptor = assets.openFd(modelFilename);
69 | FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor());
70 | FileChannel fileChannel = inputStream.getChannel();
71 | long startOffset = fileDescriptor.getStartOffset();
72 | long declaredLength = fileDescriptor.getDeclaredLength();
73 | return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength);
74 | }
75 |
76 | /**
77 | * Initializes a native TensorFlow session for classifying images.
78 | *
79 | * @param assetManager The asset manager to be used to load assets.
80 | * @param modelFilename The filepath of the model GraphDef protocol buffer.
81 | * @param labelFilename The filepath of label file for classes.
82 | * @param inputSize The input size. A square image of inputSize x inputSize is assumed.
83 | * @throws IOException
84 | */
85 | public static Classifier create(
86 | AssetManager assetManager, String modelFilename, String labelFilename, int inputSize) {
87 | TFLiteImageClassifier c = new TFLiteImageClassifier();
88 |
89 | // Read the label names into memory.
90 | // TODO(andrewharp): make this handle non-assets.
91 | Log.i(TAG, "Reading labels from: " + labelFilename);
92 | BufferedReader br = null;
93 | try {
94 | br = new BufferedReader(new InputStreamReader(assetManager.open(labelFilename)));
95 | String line;
96 | while ((line = br.readLine()) != null) {
97 | c.labels.add(line);
98 | }
99 | br.close();
100 | } catch (IOException e) {
101 | throw new RuntimeException("Problem reading label file!" , e);
102 | }
103 |
104 | c.imgData =
105 | ByteBuffer.allocateDirect(
106 | DIM_BATCH_SIZE * DIM_IMG_SIZE_X * DIM_IMG_SIZE_Y * DIM_PIXEL_SIZE);
107 |
108 | c.imgData.order(ByteOrder.nativeOrder());
109 | try {
110 | c.tfLite = new Interpreter(loadModelFile(assetManager, modelFilename));
111 | } catch (Exception e) {
112 | throw new RuntimeException(e);
113 | }
114 |
115 | // The shape of the output is [N, NUM_CLASSES], where N is the batch size.
116 | Log.i(TAG, "Read " + c.labels.size() + " labels");
117 |
118 | // Pre-allocate buffers.
119 | c.intValues = new int[inputSize * inputSize];
120 |
121 | c.labelProb = new byte[1][c.labels.size()];
122 |
123 | return c;
124 | }
125 |
126 | /** Writes Image data into a {@code ByteBuffer}. */
127 | private void convertBitmapToByteBuffer(Bitmap bitmap) {
128 | if (imgData == null) {
129 | return;
130 | }
131 | imgData.rewind();
132 | bitmap.getPixels(intValues, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
133 | // Convert the image to floating point.
134 | int pixel = 0;
135 | long startTime = SystemClock.uptimeMillis();
136 | for (int i = 0; i < DIM_IMG_SIZE_X; ++i) {
137 | for (int j = 0; j < DIM_IMG_SIZE_Y; ++j) {
138 | final int val = intValues[pixel++];
139 | imgData.put((byte) ((val >> 16) & 0xFF));
140 | imgData.put((byte) ((val >> 8) & 0xFF));
141 | imgData.put((byte) (val & 0xFF));
142 | }
143 | }
144 | long endTime = SystemClock.uptimeMillis();
145 | Log.d(TAG, "Timecost to put values into ByteBuffer: " + Long.toString(endTime - startTime));
146 | }
147 |
148 | @Override
149 | public List recognizeImage(final Bitmap bitmap) {
150 | // Log this method so that it can be analyzed with systrace.
151 | Trace.beginSection("recognizeImage");
152 |
153 | Trace.beginSection("preprocessBitmap");
154 |
155 | long startTime;
156 | long endTime;
157 | startTime = SystemClock.uptimeMillis();
158 |
159 | convertBitmapToByteBuffer(bitmap);
160 |
161 | // Run the inference call.
162 | Trace.beginSection("run");
163 | startTime = SystemClock.uptimeMillis();
164 | tfLite.run(imgData, labelProb);
165 | endTime = SystemClock.uptimeMillis();
166 | Log.i(TAG, "Inf time: " + (endTime - startTime));
167 | Trace.endSection();
168 |
169 | // Find the best classifications.
170 | PriorityQueue pq =
171 | new PriorityQueue(
172 | 3,
173 | new Comparator() {
174 | @Override
175 | public int compare(Recognition lhs, Recognition rhs) {
176 | // Intentionally reversed to put high confidence at the head of the queue.
177 | return Float.compare(rhs.getConfidence(), lhs.getConfidence());
178 | }
179 | });
180 | for (int i = 0; i < labels.size(); ++i) {
181 | pq.add(
182 | new Recognition(
183 | "" + i,
184 | labels.size() > i ? labels.get(i) : "unknown",
185 | (float) labelProb[0][i],
186 | null));
187 | }
188 | final ArrayList recognitions = new ArrayList();
189 | int recognitionsSize = Math.min(pq.size(), MAX_RESULTS);
190 | for (int i = 0; i < recognitionsSize; ++i) {
191 | recognitions.add(pq.poll());
192 | }
193 | Trace.endSection(); // "recognizeImage"
194 | return recognitions;
195 | }
196 |
197 | @Override
198 | public void enableStatLogging(boolean logStats) {
199 | }
200 |
201 | @Override
202 | public String getStatString() {
203 | return "";
204 | }
205 |
206 | @Override
207 | public void close() {
208 | }
209 | }
210 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/java/org/tensorflow/demo/TFLiteObjectDetectionAPIModel.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2016 The TensorFlow Authors. All Rights Reserved.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 | ==============================================================================*/
15 |
16 | package org.tensorflow.demo;
17 |
18 | import android.content.res.AssetFileDescriptor;
19 | import android.content.res.AssetManager;
20 | import android.graphics.Bitmap;
21 | import android.graphics.RectF;
22 | import android.os.Trace;
23 | import java.io.BufferedReader;
24 | import java.io.FileInputStream;
25 | import java.io.IOException;
26 | import java.io.InputStream;
27 | import java.io.InputStreamReader;
28 | import java.nio.ByteBuffer;
29 | import java.nio.ByteOrder;
30 | import java.nio.MappedByteBuffer;
31 | import java.nio.channels.FileChannel;
32 | import java.util.ArrayList;
33 | import java.util.HashMap;
34 | import java.util.List;
35 | import java.util.Map;
36 | import java.util.Vector;
37 | import org.tensorflow.demo.env.Logger;
38 | import org.tensorflow.lite.Interpreter;
39 |
40 | /**
41 | * Wrapper for frozen detection models trained using the Tensorflow Object Detection API:
42 | * github.com/tensorflow/models/tree/master/research/object_detection
43 | */
44 | public class TFLiteObjectDetectionAPIModel implements Classifier {
45 | private static final Logger LOGGER = new Logger();
46 |
47 | // Only return this many results.
48 | private static final int NUM_DETECTIONS = 10;
49 | private boolean isModelQuantized;
50 | // Float model
51 | private static final float IMAGE_MEAN = 128.0f;
52 | private static final float IMAGE_STD = 128.0f;
53 | // Number of threads in the java app
54 | private static final int NUM_THREADS = 4;
55 | // Config values.
56 | private int inputSize;
57 | // Pre-allocated buffers.
58 | private Vector labels = new Vector();
59 | private int[] intValues;
60 | // outputLocations: array of shape [Batchsize, NUM_DETECTIONS,4]
61 | // contains the location of detected boxes
62 | private float[][][] outputLocations;
63 | // outputClasses: array of shape [Batchsize, NUM_DETECTIONS]
64 | // contains the classes of detected boxes
65 | private float[][] outputClasses;
66 | // outputScores: array of shape [Batchsize, NUM_DETECTIONS]
67 | // contains the scores of detected boxes
68 | private float[][] outputScores;
69 | // numDetections: array of shape [Batchsize]
70 | // contains the number of detected boxes
71 | private float[] numDetections;
72 |
73 | private ByteBuffer imgData;
74 |
75 | private Interpreter tfLite;
76 |
77 |
78 | /** Memory-map the model file in Assets. */
79 | private static MappedByteBuffer loadModelFile(AssetManager assets, String modelFilename)
80 | throws IOException {
81 | AssetFileDescriptor fileDescriptor = assets.openFd(modelFilename);
82 | FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor());
83 | FileChannel fileChannel = inputStream.getChannel();
84 | long startOffset = fileDescriptor.getStartOffset();
85 | long declaredLength = fileDescriptor.getDeclaredLength();
86 | return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength);
87 | }
88 |
89 | /**
90 | * Initializes a native TensorFlow session for classifying images.
91 | *
92 | * @param assetManager The asset manager to be used to load assets.
93 | * @param modelFilename The filepath of the model GraphDef protocol buffer.
94 | * @param labelFilename The filepath of label file for classes.
95 | * @param inputSize The size of image input
96 | * @param isQuantized Boolean representing model is quantized or not
97 | */
98 | public static Classifier create(
99 | final AssetManager assetManager,
100 | final String modelFilename,
101 | final String labelFilename,
102 | final int inputSize,
103 | final boolean isQuantized)
104 | throws IOException {
105 | final TFLiteObjectDetectionAPIModel d = new TFLiteObjectDetectionAPIModel();
106 |
107 | InputStream labelsInput = null;
108 | String actualFilename = labelFilename.split("file:///android_asset/")[1];
109 | labelsInput = assetManager.open(actualFilename);
110 | BufferedReader br = null;
111 | br = new BufferedReader(new InputStreamReader(labelsInput));
112 | String line;
113 | while ((line = br.readLine()) != null) {
114 | LOGGER.w(line);
115 | d.labels.add(line);
116 | }
117 | br.close();
118 |
119 | d.inputSize = inputSize;
120 |
121 | try {
122 | d.tfLite = new Interpreter(loadModelFile(assetManager, modelFilename));
123 | } catch (Exception e) {
124 | throw new RuntimeException(e);
125 | }
126 |
127 | d.isModelQuantized = isQuantized;
128 | // Pre-allocate buffers.
129 | int numBytesPerChannel;
130 | if (isQuantized) {
131 | numBytesPerChannel = 1; // Quantized
132 | } else {
133 | numBytesPerChannel = 4; // Floating point
134 | }
135 | d.imgData = ByteBuffer.allocateDirect(1 * d.inputSize * d.inputSize * 3 * numBytesPerChannel);
136 | d.imgData.order(ByteOrder.nativeOrder());
137 | d.intValues = new int[d.inputSize * d.inputSize];
138 |
139 | d.tfLite.setNumThreads(NUM_THREADS);
140 | d.outputLocations = new float[1][NUM_DETECTIONS][4];
141 | d.outputClasses = new float[1][NUM_DETECTIONS];
142 | d.outputScores = new float[1][NUM_DETECTIONS];
143 | d.numDetections = new float[1];
144 | return d;
145 | }
146 |
147 | private TFLiteObjectDetectionAPIModel() {}
148 |
149 | @Override
150 | public List recognizeImage(final Bitmap bitmap) {
151 | // Log this method so that it can be analyzed with systrace.
152 | Trace.beginSection("recognizeImage");
153 |
154 | Trace.beginSection("preprocessBitmap");
155 | // Preprocess the image data from 0-255 int to normalized float based
156 | // on the provided parameters.
157 | bitmap.getPixels(intValues, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
158 |
159 | imgData.rewind();
160 | for (int i = 0; i < inputSize; ++i) {
161 | for (int j = 0; j < inputSize; ++j) {
162 | int pixelValue = intValues[i * inputSize + j];
163 | if (isModelQuantized) {
164 | // Quantized model
165 | imgData.put((byte) ((pixelValue >> 16) & 0xFF));
166 | imgData.put((byte) ((pixelValue >> 8) & 0xFF));
167 | imgData.put((byte) (pixelValue & 0xFF));
168 | } else { // Float model
169 | imgData.putFloat((((pixelValue >> 16) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
170 | imgData.putFloat((((pixelValue >> 8) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
171 | imgData.putFloat(((pixelValue & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
172 | }
173 | }
174 | }
175 | Trace.endSection(); // preprocessBitmap
176 |
177 | // Copy the input data into TensorFlow.
178 | Trace.beginSection("feed");
179 | outputLocations = new float[1][NUM_DETECTIONS][4];
180 | outputClasses = new float[1][NUM_DETECTIONS];
181 | outputScores = new float[1][NUM_DETECTIONS];
182 | numDetections = new float[1];
183 |
184 | Object[] inputArray = {imgData};
185 | Map outputMap = new HashMap<>();
186 | outputMap.put(0, outputLocations);
187 | outputMap.put(1, outputClasses);
188 | outputMap.put(2, outputScores);
189 | outputMap.put(3, numDetections);
190 | Trace.endSection();
191 |
192 | // Run the inference call.
193 | Trace.beginSection("run");
194 | tfLite.runForMultipleInputsOutputs(inputArray, outputMap);
195 | Trace.endSection();
196 |
197 | // Show the best detections.
198 | // after scaling them back to the input size.
199 | final ArrayList recognitions = new ArrayList<>(NUM_DETECTIONS);
200 | for (int i = 0; i < NUM_DETECTIONS; ++i) {
201 | final RectF detection =
202 | new RectF(
203 | outputLocations[0][i][1] * inputSize,
204 | outputLocations[0][i][0] * inputSize,
205 | outputLocations[0][i][3] * inputSize,
206 | outputLocations[0][i][2] * inputSize);
207 | // SSD Mobilenet V1 Model assumes class 0 is background class
208 | // in label file and class labels start from 1 to number_of_classes+1,
209 | // while outputClasses correspond to class index from 0 to number_of_classes
210 | int labelOffset = 1;
211 | recognitions.add(
212 | new Recognition(
213 | "" + i,
214 | labels.get((int) outputClasses[0][i] + labelOffset),
215 | outputScores[0][i],
216 | detection));
217 | }
218 | Trace.endSection(); // "recognizeImage"
219 | return recognitions;
220 | }
221 |
222 | @Override
223 | public void enableStatLogging(final boolean logStats) {
224 | }
225 |
226 | @Override
227 | public String getStatString() {
228 | return "";
229 | }
230 |
231 | @Override
232 | public void close() {
233 | }
234 | }
235 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/java/org/tensorflow/demo/env/AssetUtils.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 | ==============================================================================*/
15 |
16 | package org.tensorflow.demo.env;
17 |
18 | import android.content.Context;
19 | import android.content.res.AssetManager;
20 | import android.util.Log;
21 | import java.io.File;
22 | import java.io.FileOutputStream;
23 | import java.io.IOException;
24 | import java.io.InputStream;
25 | import java.io.OutputStream;
26 |
27 | /** Utilities for dealing with assets. */
28 | public class AssetUtils {
29 |
30 | private static final String TAG = AssetUtils.class.getSimpleName();
31 |
32 | private static final int BYTE_BUF_SIZE = 2048;
33 |
34 | /**
35 | * Copies a file from assets.
36 | *
37 | * @param context application context used to discover assets.
38 | * @param assetName the relative file name within assets.
39 | * @param targetName the target file name, always over write the existing file.
40 | * @throws IOException if operation fails.
41 | */
42 | public static void copy(Context context, String assetName, String targetName) throws IOException {
43 |
44 | Log.d(TAG, "creating file " + targetName + " from " + assetName);
45 |
46 | File targetFile = null;
47 | InputStream inputStream = null;
48 | FileOutputStream outputStream = null;
49 |
50 | try {
51 | AssetManager assets = context.getAssets();
52 | targetFile = new File(targetName);
53 | inputStream = assets.open(assetName);
54 | // TODO(kanlig): refactor log messages to make them more useful.
55 | Log.d(TAG, "Creating outputstream");
56 | outputStream = new FileOutputStream(targetFile, false /* append */);
57 | copy(inputStream, outputStream);
58 | } finally {
59 | if (outputStream != null) {
60 | outputStream.close();
61 | }
62 | if (inputStream != null) {
63 | inputStream.close();
64 | }
65 | }
66 | }
67 |
68 | private static void copy(InputStream from, OutputStream to) throws IOException {
69 | byte[] buf = new byte[BYTE_BUF_SIZE];
70 | while (true) {
71 | int r = from.read(buf);
72 | if (r == -1) {
73 | break;
74 | }
75 | to.write(buf, 0, r);
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/java/org/tensorflow/demo/env/BorderedText.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2016 The TensorFlow Authors. All Rights Reserved.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 | ==============================================================================*/
15 |
16 | package org.tensorflow.demo.env;
17 |
18 | import android.graphics.Canvas;
19 | import android.graphics.Color;
20 | import android.graphics.Paint;
21 | import android.graphics.Paint.Align;
22 | import android.graphics.Paint.Style;
23 | import android.graphics.Rect;
24 | import android.graphics.Typeface;
25 | import java.util.Vector;
26 |
27 | /**
28 | * A class that encapsulates the tedious bits of rendering legible, bordered text onto a canvas.
29 | */
30 | public class BorderedText {
31 | private final Paint interiorPaint;
32 | private final Paint exteriorPaint;
33 |
34 | private final float textSize;
35 |
36 | /**
37 | * Creates a left-aligned bordered text object with a white interior, and a black exterior with
38 | * the specified text size.
39 | *
40 | * @param textSize text size in pixels
41 | */
42 | public BorderedText(final float textSize) {
43 | this(Color.WHITE, Color.BLACK, textSize);
44 | }
45 |
46 | /**
47 | * Create a bordered text object with the specified interior and exterior colors, text size and
48 | * alignment.
49 | *
50 | * @param interiorColor the interior text color
51 | * @param exteriorColor the exterior text color
52 | * @param textSize text size in pixels
53 | */
54 | public BorderedText(final int interiorColor, final int exteriorColor, final float textSize) {
55 | interiorPaint = new Paint();
56 | interiorPaint.setTextSize(textSize);
57 | interiorPaint.setColor(interiorColor);
58 | interiorPaint.setStyle(Style.FILL);
59 | interiorPaint.setAntiAlias(false);
60 | interiorPaint.setAlpha(255);
61 |
62 | exteriorPaint = new Paint();
63 | exteriorPaint.setTextSize(textSize);
64 | exteriorPaint.setColor(exteriorColor);
65 | exteriorPaint.setStyle(Style.FILL_AND_STROKE);
66 | exteriorPaint.setStrokeWidth(textSize / 8);
67 | exteriorPaint.setAntiAlias(false);
68 | exteriorPaint.setAlpha(255);
69 |
70 | this.textSize = textSize;
71 | }
72 |
73 | public void setTypeface(Typeface typeface) {
74 | interiorPaint.setTypeface(typeface);
75 | exteriorPaint.setTypeface(typeface);
76 | }
77 |
78 | public void drawText(final Canvas canvas, final float posX, final float posY, final String text) {
79 | canvas.drawText(text, posX, posY, exteriorPaint);
80 | canvas.drawText(text, posX, posY, interiorPaint);
81 | }
82 |
83 | public void drawLines(Canvas canvas, final float posX, final float posY, Vector lines) {
84 | int lineNum = 0;
85 | for (final String line : lines) {
86 | drawText(canvas, posX, posY - getTextSize() * (lines.size() - lineNum - 1), line);
87 | ++lineNum;
88 | }
89 | }
90 |
91 | public void setInteriorColor(final int color) {
92 | interiorPaint.setColor(color);
93 | }
94 |
95 | public void setExteriorColor(final int color) {
96 | exteriorPaint.setColor(color);
97 | }
98 |
99 | public float getTextSize() {
100 | return textSize;
101 | }
102 |
103 | public void setAlpha(final int alpha) {
104 | interiorPaint.setAlpha(alpha);
105 | exteriorPaint.setAlpha(alpha);
106 | }
107 |
108 | public void getTextBounds(
109 | final String line, final int index, final int count, final Rect lineBounds) {
110 | interiorPaint.getTextBounds(line, index, count, lineBounds);
111 | }
112 |
113 | public void setTextAlign(final Align align) {
114 | interiorPaint.setTextAlign(align);
115 | exteriorPaint.setTextAlign(align);
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/java/org/tensorflow/demo/env/Logger.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 | ==============================================================================*/
15 |
16 | package org.tensorflow.demo.env;
17 |
18 | import android.util.Log;
19 | import java.util.HashSet;
20 | import java.util.Set;
21 |
22 | /**
23 | * Wrapper for the platform log function, allows convenient message prefixing and log disabling.
24 | */
25 | public final class Logger {
26 | private static final String DEFAULT_TAG = "tensorflow";
27 | private static final int DEFAULT_MIN_LOG_LEVEL = Log.DEBUG;
28 |
29 | // Classes to be ignored when examining the stack trace
30 | private static final Set IGNORED_CLASS_NAMES;
31 |
32 | static {
33 | IGNORED_CLASS_NAMES = new HashSet(3);
34 | IGNORED_CLASS_NAMES.add("dalvik.system.VMStack");
35 | IGNORED_CLASS_NAMES.add("java.lang.Thread");
36 | IGNORED_CLASS_NAMES.add(Logger.class.getCanonicalName());
37 | }
38 |
39 | private final String tag;
40 | private final String messagePrefix;
41 | private int minLogLevel = DEFAULT_MIN_LOG_LEVEL;
42 |
43 | /**
44 | * Creates a Logger using the class name as the message prefix.
45 | *
46 | * @param clazz the simple name of this class is used as the message prefix.
47 | */
48 | public Logger(final Class> clazz) {
49 | this(clazz.getSimpleName());
50 | }
51 |
52 | /**
53 | * Creates a Logger using the specified message prefix.
54 | *
55 | * @param messagePrefix is prepended to the text of every message.
56 | */
57 | public Logger(final String messagePrefix) {
58 | this(DEFAULT_TAG, messagePrefix);
59 | }
60 |
61 | /**
62 | * Creates a Logger with a custom tag and a custom message prefix. If the message prefix
63 | * is set to null
, the caller's class name is used as the prefix.
64 | *
65 | * @param tag identifies the source of a log message.
66 | * @param messagePrefix prepended to every message if non-null. If null, the name of the caller is
67 | * being used
68 | */
69 | public Logger(final String tag, final String messagePrefix) {
70 | this.tag = tag;
71 | final String prefix = messagePrefix == null ? getCallerSimpleName() : messagePrefix;
72 | this.messagePrefix = (prefix.length() > 0) ? prefix + ": " : prefix;
73 | }
74 |
75 | /**
76 | * Creates a Logger using the caller's class name as the message prefix.
77 | */
78 | public Logger() {
79 | this(DEFAULT_TAG, null);
80 | }
81 |
82 | /**
83 | * Creates a Logger using the caller's class name as the message prefix.
84 | */
85 | public Logger(final int minLogLevel) {
86 | this(DEFAULT_TAG, null);
87 | this.minLogLevel = minLogLevel;
88 | }
89 |
90 | public void setMinLogLevel(final int minLogLevel) {
91 | this.minLogLevel = minLogLevel;
92 | }
93 |
94 | public boolean isLoggable(final int logLevel) {
95 | return logLevel >= minLogLevel || Log.isLoggable(tag, logLevel);
96 | }
97 |
98 | /**
99 | * Return caller's simple name.
100 | *
101 | * Android getStackTrace() returns an array that looks like this:
102 | * stackTrace[0]: dalvik.system.VMStack
103 | * stackTrace[1]: java.lang.Thread
104 | * stackTrace[2]: com.google.android.apps.unveil.env.UnveilLogger
105 | * stackTrace[3]: com.google.android.apps.unveil.BaseApplication
106 | *
107 | * This function returns the simple version of the first non-filtered name.
108 | *
109 | * @return caller's simple name
110 | */
111 | private static String getCallerSimpleName() {
112 | // Get the current callstack so we can pull the class of the caller off of it.
113 | final StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
114 |
115 | for (final StackTraceElement elem : stackTrace) {
116 | final String className = elem.getClassName();
117 | if (!IGNORED_CLASS_NAMES.contains(className)) {
118 | // We're only interested in the simple name of the class, not the complete package.
119 | final String[] classParts = className.split("\\.");
120 | return classParts[classParts.length - 1];
121 | }
122 | }
123 |
124 | return Logger.class.getSimpleName();
125 | }
126 |
127 | private String toMessage(final String format, final Object... args) {
128 | return messagePrefix + (args.length > 0 ? String.format(format, args) : format);
129 | }
130 |
131 | public void v(final String format, final Object... args) {
132 | if (isLoggable(Log.VERBOSE)) {
133 | Log.v(tag, toMessage(format, args));
134 | }
135 | }
136 |
137 | public void v(final Throwable t, final String format, final Object... args) {
138 | if (isLoggable(Log.VERBOSE)) {
139 | Log.v(tag, toMessage(format, args), t);
140 | }
141 | }
142 |
143 | public void d(final String format, final Object... args) {
144 | if (isLoggable(Log.DEBUG)) {
145 | Log.d(tag, toMessage(format, args));
146 | }
147 | }
148 |
149 | public void d(final Throwable t, final String format, final Object... args) {
150 | if (isLoggable(Log.DEBUG)) {
151 | Log.d(tag, toMessage(format, args), t);
152 | }
153 | }
154 |
155 | public void i(final String format, final Object... args) {
156 | if (isLoggable(Log.INFO)) {
157 | Log.i(tag, toMessage(format, args));
158 | }
159 | }
160 |
161 | public void i(final Throwable t, final String format, final Object... args) {
162 | if (isLoggable(Log.INFO)) {
163 | Log.i(tag, toMessage(format, args), t);
164 | }
165 | }
166 |
167 | public void w(final String format, final Object... args) {
168 | if (isLoggable(Log.WARN)) {
169 | Log.w(tag, toMessage(format, args));
170 | }
171 | }
172 |
173 | public void w(final Throwable t, final String format, final Object... args) {
174 | if (isLoggable(Log.WARN)) {
175 | Log.w(tag, toMessage(format, args), t);
176 | }
177 | }
178 |
179 | public void e(final String format, final Object... args) {
180 | if (isLoggable(Log.ERROR)) {
181 | Log.e(tag, toMessage(format, args));
182 | }
183 | }
184 |
185 | public void e(final Throwable t, final String format, final Object... args) {
186 | if (isLoggable(Log.ERROR)) {
187 | Log.e(tag, toMessage(format, args), t);
188 | }
189 | }
190 | }
191 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/java/org/tensorflow/demo/env/Size.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2016 The TensorFlow Authors. All Rights Reserved.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 | ==============================================================================*/
15 |
16 | package org.tensorflow.demo.env;
17 |
18 | import android.graphics.Bitmap;
19 | import android.text.TextUtils;
20 | import java.io.Serializable;
21 | import java.util.ArrayList;
22 | import java.util.List;
23 |
24 | /**
25 | * Size class independent of a Camera object.
26 | */
27 | public class Size implements Comparable, Serializable {
28 |
29 | // 1.4 went out with this UID so we'll need to maintain it to preserve pending queries when
30 | // upgrading.
31 | public static final long serialVersionUID = 7689808733290872361L;
32 |
33 | public final int width;
34 | public final int height;
35 |
36 | public Size(final int width, final int height) {
37 | this.width = width;
38 | this.height = height;
39 | }
40 |
41 | public Size(final Bitmap bmp) {
42 | this.width = bmp.getWidth();
43 | this.height = bmp.getHeight();
44 | }
45 |
46 | /**
47 | * Rotate a size by the given number of degrees.
48 | * @param size Size to rotate.
49 | * @param rotation Degrees {0, 90, 180, 270} to rotate the size.
50 | * @return Rotated size.
51 | */
52 | public static Size getRotatedSize(final Size size, final int rotation) {
53 | if (rotation % 180 != 0) {
54 | // The phone is portrait, therefore the camera is sideways and frame should be rotated.
55 | return new Size(size.height, size.width);
56 | }
57 | return size;
58 | }
59 |
60 | public static Size parseFromString(String sizeString) {
61 | if (TextUtils.isEmpty(sizeString)) {
62 | return null;
63 | }
64 |
65 | sizeString = sizeString.trim();
66 |
67 | // The expected format is "x".
68 | final String[] components = sizeString.split("x");
69 | if (components.length == 2) {
70 | try {
71 | final int width = Integer.parseInt(components[0]);
72 | final int height = Integer.parseInt(components[1]);
73 | return new Size(width, height);
74 | } catch (final NumberFormatException e) {
75 | return null;
76 | }
77 | } else {
78 | return null;
79 | }
80 | }
81 |
82 | public static List sizeStringToList(final String sizes) {
83 | final List sizeList = new ArrayList();
84 | if (sizes != null) {
85 | final String[] pairs = sizes.split(",");
86 | for (final String pair : pairs) {
87 | final Size size = Size.parseFromString(pair);
88 | if (size != null) {
89 | sizeList.add(size);
90 | }
91 | }
92 | }
93 | return sizeList;
94 | }
95 |
96 | public static String sizeListToString(final List sizes) {
97 | String sizesString = "";
98 | if (sizes != null && sizes.size() > 0) {
99 | sizesString = sizes.get(0).toString();
100 | for (int i = 1; i < sizes.size(); i++) {
101 | sizesString += "," + sizes.get(i).toString();
102 | }
103 | }
104 | return sizesString;
105 | }
106 |
107 | public final float aspectRatio() {
108 | return (float) width / (float) height;
109 | }
110 |
111 | @Override
112 | public int compareTo(final Size other) {
113 | return width * height - other.width * other.height;
114 | }
115 |
116 | @Override
117 | public boolean equals(final Object other) {
118 | if (other == null) {
119 | return false;
120 | }
121 |
122 | if (!(other instanceof Size)) {
123 | return false;
124 | }
125 |
126 | final Size otherSize = (Size) other;
127 | return (width == otherSize.width && height == otherSize.height);
128 | }
129 |
130 | @Override
131 | public int hashCode() {
132 | return width * 32713 + height;
133 | }
134 |
135 | @Override
136 | public String toString() {
137 | return dimensionsAsString(width, height);
138 | }
139 |
140 | public static final String dimensionsAsString(final int width, final int height) {
141 | return width + "x" + height;
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/java/org/tensorflow/demo/env/SplitTimer.java:
--------------------------------------------------------------------------------
1 | /* Copyright 2016 The TensorFlow Authors. All Rights Reserved.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 | ==============================================================================*/
15 |
16 | package org.tensorflow.demo.env;
17 |
18 | import android.os.SystemClock;
19 |
20 | /**
21 | * A simple utility timer for measuring CPU time and wall-clock splits.
22 | */
23 | public class SplitTimer {
24 | private final Logger logger;
25 |
26 | private long lastWallTime;
27 | private long lastCpuTime;
28 |
29 | public SplitTimer(final String name) {
30 | logger = new Logger(name);
31 | newSplit();
32 | }
33 |
34 | public void newSplit() {
35 | lastWallTime = SystemClock.uptimeMillis();
36 | lastCpuTime = SystemClock.currentThreadTimeMillis();
37 | }
38 |
39 | public void endSplit(final String splitName) {
40 | final long currWallTime = SystemClock.uptimeMillis();
41 | final long currCpuTime = SystemClock.currentThreadTimeMillis();
42 |
43 | logger.i(
44 | "%s: cpu=%dms wall=%dms",
45 | splitName, currCpuTime - lastCpuTime, currWallTime - lastWallTime);
46 |
47 | lastWallTime = currWallTime;
48 | lastCpuTime = currCpuTime;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/jnilibs/arm64-v8a/libtensorflow_demo.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TfLiteCameraDemo/app/src/main/jnilibs/arm64-v8a/libtensorflow_demo.so
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/jnilibs/arm64-v8a/libtensorflowlite_jni.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TfLiteCameraDemo/app/src/main/jnilibs/arm64-v8a/libtensorflowlite_jni.so
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/animator/color_animation.xml:
--------------------------------------------------------------------------------
1 |
16 |
18 |
24 |
30 |
31 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/drawable-hdpi/ic_action_info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TfLiteCameraDemo/app/src/main/res/drawable-hdpi/ic_action_info.png
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TfLiteCameraDemo/app/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/drawable-hdpi/tile.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TfLiteCameraDemo/app/src/main/res/drawable-hdpi/tile.9.png
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/drawable-mdpi/ic_action_info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TfLiteCameraDemo/app/src/main/res/drawable-mdpi/ic_action_info.png
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TfLiteCameraDemo/app/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/drawable-xhdpi/ic_action_info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TfLiteCameraDemo/app/src/main/res/drawable-xhdpi/ic_action_info.png
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TfLiteCameraDemo/app/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/drawable-xxhdpi/ic_action_info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TfLiteCameraDemo/app/src/main/res/drawable-xxhdpi/ic_action_info.png
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TfLiteCameraDemo/app/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/drawable/border.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/layout/activity_camera.xml:
--------------------------------------------------------------------------------
1 |
16 |
23 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/layout/activity_speech.xml:
--------------------------------------------------------------------------------
1 |
16 |
23 |
24 |
35 |
36 |
45 |
46 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/layout/camera_connection_fragment.xml:
--------------------------------------------------------------------------------
1 |
16 |
19 |
20 |
25 |
26 |
31 |
32 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/layout/camera_connection_fragment_stylize.xml:
--------------------------------------------------------------------------------
1 |
16 |
20 |
25 |
26 |
31 |
32 |
39 |
40 |
45 |
46 |
51 |
52 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/layout/camera_connection_fragment_tracking.xml:
--------------------------------------------------------------------------------
1 |
16 |
19 |
20 |
24 |
25 |
29 |
30 |
34 |
35 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/layout/list_text_item.xml:
--------------------------------------------------------------------------------
1 |
16 |
26 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/values-sw600dp/template-dimens.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 | @dimen/margin_huge
22 | @dimen/margin_medium
23 |
24 |
25 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/values-sw600dp/template-styles.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
11 |
12 |
19 |
20 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/values-v11/template-styles.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/values-v21/base-colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/values-v21/base-template-styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/values/base-strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 | TFLite Demo
20 | TFL Classify
21 | TFL Detect
22 | TFL Speech
23 |
24 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | #cc4285f4
19 |
20 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 | Info
18 | This sample needs camera permission.
19 | This device doesn\'t support Camera2 API.
20 |
21 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/values/template-dimens.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 | 4dp
22 | 8dp
23 | 16dp
24 | 32dp
25 | 64dp
26 |
27 |
28 |
29 | @dimen/margin_medium
30 | @dimen/margin_medium
31 |
32 |
33 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/app/src/main/res/values/template-styles.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
34 |
35 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:3.0.1'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
21 | task clean(type: Delete) {
22 | delete rootProject.buildDir
23 | }
24 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Robinatp/Tensorflow_Lite_Demo/e675b8da540b4d2f5db65342fe59225973f48940/TfLiteCameraDemo/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/TfLiteCameraDemo/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Sep 28 09:01:41 PDT 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
7 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/local.properties:
--------------------------------------------------------------------------------
1 | ## This file is automatically generated by Android Studio.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must *NOT* be checked into Version Control Systems,
5 | # as it contains information specific to your local configuration.
6 | #
7 | # Location of the SDK. This is only used by Gradle.
8 | # For customization when using a Version Control System, please read the
9 | # header note.
10 | #Thu Aug 16 08:55:33 CST 2018
11 | sdk.dir=/home/zhangbin/Android/Sdk
12 |
--------------------------------------------------------------------------------
/TfLiteCameraDemo/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------