From c3c417f579d417b8fd68f6364d41383c506d543f Mon Sep 17 00:00:00 2001 From: authorfu Date: Mon, 27 Jul 2020 11:11:50 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E6=B7=BB=E5=8A=A0mini=20demo=202.=20ui?= =?UTF-8?q?=E5=8D=87=E7=BA=A7=E5=88=B0androidx?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy/android_demo/app/build.gradle | 11 +- .../app/src/main/AndroidManifest.xml | 4 +- .../demo/ocr/AppCompatPreferenceActivity.java | 11 +- .../paddle/lite/demo/ocr/MainActivity.java | 11 +- .../paddle/lite/demo/ocr/MiniActivity.java | 156 ++++++++++++++++++ .../baidu/paddle/lite/demo/ocr/Predictor.java | 20 ++- .../lite/demo/ocr/SettingsActivity.java | 3 +- .../app/src/main/res/layout/activity_main.xml | 4 +- .../app/src/main/res/layout/activity_mini.xml | 46 ++++++ 9 files changed, 238 insertions(+), 28 deletions(-) create mode 100644 deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/MiniActivity.java create mode 100644 deploy/android_demo/app/src/main/res/layout/activity_mini.xml diff --git a/deploy/android_demo/app/build.gradle b/deploy/android_demo/app/build.gradle index adf3968b..5ecb1169 100644 --- a/deploy/android_demo/app/build.gradle +++ b/deploy/android_demo/app/build.gradle @@ -3,11 +3,11 @@ import java.security.MessageDigest apply plugin: 'com.android.application' android { - compileSdkVersion 28 + compileSdkVersion 29 defaultConfig { applicationId "com.baidu.paddle.lite.demo.ocr" - minSdkVersion 15 - targetSdkVersion 28 + minSdkVersion 23 + targetSdkVersion 29 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" @@ -39,9 +39,8 @@ android { dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') - implementation 'com.android.support:appcompat-v7:28.0.0' - implementation 'com.android.support.constraint:constraint-layout:1.1.3' - implementation 'com.android.support:design:28.0.0' + implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' diff --git a/deploy/android_demo/app/src/main/AndroidManifest.xml b/deploy/android_demo/app/src/main/AndroidManifest.xml index b7c1d8b5..54482b1d 100644 --- a/deploy/android_demo/app/src/main/AndroidManifest.xml +++ b/deploy/android_demo/app/src/main/AndroidManifest.xml @@ -14,10 +14,10 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> + - @@ -26,7 +26,7 @@ android:label="Settings"> diff --git a/deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/AppCompatPreferenceActivity.java b/deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/AppCompatPreferenceActivity.java index 397e4e39..49af0afe 100644 --- a/deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/AppCompatPreferenceActivity.java +++ b/deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/AppCompatPreferenceActivity.java @@ -19,15 +19,16 @@ package com.baidu.paddle.lite.demo.ocr; import android.content.res.Configuration; import android.os.Bundle; import android.preference.PreferenceActivity; -import android.support.annotation.LayoutRes; -import android.support.annotation.Nullable; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatDelegate; -import android.support.v7.widget.Toolbar; import android.view.MenuInflater; import android.view.View; import android.view.ViewGroup; +import androidx.annotation.LayoutRes; +import androidx.annotation.Nullable; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatDelegate; +import androidx.appcompat.widget.Toolbar; + /** * A {@link PreferenceActivity} which implements and proxies the necessary calls * to be used with AppCompat. diff --git a/deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/MainActivity.java b/deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/MainActivity.java index 716e7bdd..afb261dc 100644 --- a/deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/MainActivity.java +++ b/deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/MainActivity.java @@ -19,11 +19,6 @@ import android.os.HandlerThread; import android.os.Message; import android.preference.PreferenceManager; import android.provider.MediaStore; -import android.support.annotation.NonNull; -import android.support.v4.app.ActivityCompat; -import android.support.v4.content.ContextCompat; -import android.support.v4.content.FileProvider; -import android.support.v7.app.AppCompatActivity; import android.text.method.ScrollingMovementMethod; import android.util.Log; import android.view.Menu; @@ -33,6 +28,12 @@ import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; +import androidx.core.content.FileProvider; + import java.io.File; import java.io.IOException; import java.io.InputStream; diff --git a/deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/MiniActivity.java b/deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/MiniActivity.java new file mode 100644 index 00000000..b40cd5f0 --- /dev/null +++ b/deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/MiniActivity.java @@ -0,0 +1,156 @@ +package com.baidu.paddle.lite.demo.ocr; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Message; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.appcompat.app.AppCompatActivity; + +import java.io.IOException; +import java.io.InputStream; + +public class MiniActivity extends AppCompatActivity { + + + public static final int REQUEST_LOAD_MODEL = 0; + public static final int REQUEST_RUN_MODEL = 1; + public static final int REQUEST_UNLOAD_MODEL = 2; + public static final int RESPONSE_LOAD_MODEL_SUCCESSED = 0; + public static final int RESPONSE_LOAD_MODEL_FAILED = 1; + public static final int RESPONSE_RUN_MODEL_SUCCESSED = 2; + public static final int RESPONSE_RUN_MODEL_FAILED = 3; + + private static final String TAG = "MiniActivity"; + + protected Handler receiver = null; // Receive messages from worker thread + protected Handler sender = null; // Send command to worker thread + protected HandlerThread worker = null; // Worker thread to load&run model + protected volatile Predictor predictor = null; + + private String assetModelDirPath = "models/ocr_v1_for_cpu"; + private String assetlabelFilePath = "labels/ppocr_keys_v1.txt"; + + private Button button; + private ImageView imageView; // 显示图像 + private TextView textView; // 显示结果 + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mini); + + Log.i(TAG, "SHOW in Logcat"); + + // Prepare the worker thread for mode loading and inference + worker = new HandlerThread("Predictor Worker"); + worker.start(); + sender = new Handler(worker.getLooper()) { + public void handleMessage(Message msg) { + switch (msg.what) { + case REQUEST_LOAD_MODEL: + // Load model and reload test image + if (!onLoadModel()) { + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(MiniActivity.this, "Load model failed!", Toast.LENGTH_SHORT).show(); + } + }); + } + break; + case REQUEST_RUN_MODEL: + // Run model if model is loaded + final boolean isSuccessed = onRunModel(); + runOnUiThread(new Runnable() { + @Override + public void run() { + if (isSuccessed){ + onRunModelSuccessed(); + }else{ + Toast.makeText(MiniActivity.this, "Run model failed!", Toast.LENGTH_SHORT).show(); + } + } + }); + break; + } + } + }; + sender.sendEmptyMessage(REQUEST_LOAD_MODEL); // 对应上面的REQUEST_LOAD_MODEL, 调用onLoadModel() + + imageView = findViewById(R.id.imageView); + textView = findViewById(R.id.sample_text); + button = findViewById(R.id.button); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + sender.sendEmptyMessage(REQUEST_RUN_MODEL); + } + }); + + + } + + @Override + protected void onDestroy() { + onUnloadModel(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + worker.quitSafely(); + } else { + worker.quit(); + } + super.onDestroy(); + } + + /** + * onCreate的时候调用, 模型初始化 + * + * @return + */ + private boolean onLoadModel() { + if (predictor == null) { + predictor = new Predictor(); + } + return predictor.init(this, assetModelDirPath, assetlabelFilePath); + } + + /** + * on + * + * @return + */ + private boolean onRunModel() { + try { + String assetImagePath = "images/5.jpg"; + InputStream imageStream = getAssets().open(assetImagePath); + Bitmap image = BitmapFactory.decodeStream(imageStream); + // 这里输入是Bitmap + predictor.setInputImage(image); + return predictor.isLoaded() && predictor.runModel(); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } + + private void onRunModelSuccessed() { + Log.i(TAG, "onRunModelSuccessed"); + textView.setText(predictor.outputResult); + imageView.setImageBitmap(predictor.outputImage); + } + + private void onUnloadModel() { + if (predictor != null) { + predictor.releaseModel(); + } + } +} diff --git a/deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/Predictor.java b/deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/Predictor.java index 7543acee..0eedf3dc 100644 --- a/deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/Predictor.java +++ b/deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/Predictor.java @@ -38,7 +38,7 @@ public class Predictor { protected float scoreThreshold = 0.1f; protected Bitmap inputImage = null; protected Bitmap outputImage = null; - protected String outputResult = ""; + protected volatile String outputResult = ""; protected float preprocessTime = 0; protected float postprocessTime = 0; @@ -46,6 +46,16 @@ public class Predictor { public Predictor() { } + public boolean init(Context appCtx, String modelPath, String labelPath) { + isLoaded = loadModel(appCtx, modelPath, cpuThreadNum, cpuPowerMode); + if (!isLoaded) { + return false; + } + isLoaded = loadLabel(appCtx, labelPath); + return isLoaded; + } + + public boolean init(Context appCtx, String modelPath, String labelPath, int cpuThreadNum, String cpuPowerMode, String inputColorFormat, long[] inputShape, float[] inputMean, @@ -76,11 +86,7 @@ public class Predictor { Log.e(TAG, "Only BGR color format is supported."); return false; } - isLoaded = loadModel(appCtx, modelPath, cpuThreadNum, cpuPowerMode); - if (!isLoaded) { - return false; - } - isLoaded = loadLabel(appCtx, labelPath); + boolean isLoaded = init(appCtx, modelPath, labelPath); if (!isLoaded) { return false; } @@ -317,7 +323,7 @@ public class Predictor { for (Point p : result.getPoints()) { sb.append("(").append(p.x).append(",").append(p.y).append(") "); } - Log.i(TAG, sb.toString()); + Log.i(TAG, sb.toString()); // 这里在logcat里打印结果 outputResultSb.append(i + 1).append(": ").append(result.getLabel()).append("\n"); } outputResult = outputResultSb.toString(); diff --git a/deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/SettingsActivity.java b/deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/SettingsActivity.java index 28727e60..b3653ccc 100644 --- a/deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/SettingsActivity.java +++ b/deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/SettingsActivity.java @@ -5,7 +5,8 @@ import android.os.Bundle; import android.preference.CheckBoxPreference; import android.preference.EditTextPreference; import android.preference.ListPreference; -import android.support.v7.app.ActionBar; + +import androidx.appcompat.app.ActionBar; import java.util.ArrayList; import java.util.List; diff --git a/deploy/android_demo/app/src/main/res/layout/activity_main.xml b/deploy/android_demo/app/src/main/res/layout/activity_main.xml index 98b9bc1a..adc70e20 100644 --- a/deploy/android_demo/app/src/main/res/layout/activity_main.xml +++ b/deploy/android_demo/app/src/main/res/layout/activity_main.xml @@ -1,5 +1,5 @@ - - \ No newline at end of file + \ No newline at end of file diff --git a/deploy/android_demo/app/src/main/res/layout/activity_mini.xml b/deploy/android_demo/app/src/main/res/layout/activity_mini.xml new file mode 100644 index 00000000..ec4622ae --- /dev/null +++ b/deploy/android_demo/app/src/main/res/layout/activity_mini.xml @@ -0,0 +1,46 @@ + + + + + + + + +