Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
wangsen
paddle_dbnet
Commits
19eb7eb8
Commit
19eb7eb8
authored
Sep 03, 2021
by
Leif
Browse files
Merge remote-tracking branch 'origin/dygraph' into dy1
parents
0afe6c32
03b7daa5
Changes
364
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
2207 additions
and
0 deletions
+2207
-0
deploy/android_demo/app/src/main/cpp/predictor_output.h
deploy/android_demo/app/src/main/cpp/predictor_output.h
+31
-0
deploy/android_demo/app/src/main/cpp/preprocess.cpp
deploy/android_demo/app/src/main/cpp/preprocess.cpp
+82
-0
deploy/android_demo/app/src/main/cpp/preprocess.h
deploy/android_demo/app/src/main/cpp/preprocess.h
+12
-0
deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/AppCompatPreferenceActivity.java
...idu/paddle/lite/demo/ocr/AppCompatPreferenceActivity.java
+128
-0
deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/MainActivity.java
...ain/java/com/baidu/paddle/lite/demo/ocr/MainActivity.java
+509
-0
deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/MiniActivity.java
...ain/java/com/baidu/paddle/lite/demo/ocr/MiniActivity.java
+157
-0
deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/OCRPredictorNative.java
...va/com/baidu/paddle/lite/demo/ocr/OCRPredictorNative.java
+102
-0
deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/OcrResultModel.java
...n/java/com/baidu/paddle/lite/demo/ocr/OcrResultModel.java
+52
-0
deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/Predictor.java
...c/main/java/com/baidu/paddle/lite/demo/ocr/Predictor.java
+356
-0
deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/SettingsActivity.java
...java/com/baidu/paddle/lite/demo/ocr/SettingsActivity.java
+201
-0
deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/Utils.java
...p/src/main/java/com/baidu/paddle/lite/demo/ocr/Utils.java
+159
-0
deploy/android_demo/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
.../app/src/main/res/drawable-v24/ic_launcher_foreground.xml
+34
-0
deploy/android_demo/app/src/main/res/drawable/ic_launcher_background.xml
...demo/app/src/main/res/drawable/ic_launcher_background.xml
+170
-0
deploy/android_demo/app/src/main/res/layout/activity_main.xml
...oy/android_demo/app/src/main/res/layout/activity_main.xml
+148
-0
deploy/android_demo/app/src/main/res/layout/activity_mini.xml
...oy/android_demo/app/src/main/res/layout/activity_mini.xml
+46
-0
deploy/android_demo/app/src/main/res/menu/menu_action_options.xml
...ndroid_demo/app/src/main/res/menu/menu_action_options.xml
+10
-0
deploy/android_demo/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
...d_demo/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
+5
-0
deploy/android_demo/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
.../app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
+5
-0
deploy/android_demo/app/src/main/res/mipmap-hdpi/ic_launcher.png
...android_demo/app/src/main/res/mipmap-hdpi/ic_launcher.png
+0
-0
deploy/android_demo/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
...d_demo/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
+0
-0
No files found.
deploy/android_demo/app/src/main/cpp/predictor_output.h
0 → 100644
View file @
19eb7eb8
#pragma once
#include "common.h"
#include <paddle_api.h>
#include <vector>
namespace
ppredictor
{
class
PredictorOutput
{
public:
PredictorOutput
()
{}
PredictorOutput
(
std
::
unique_ptr
<
const
paddle
::
lite_api
::
Tensor
>
&&
tensor
,
int
index
,
int
net_flag
)
:
_tensor
(
std
::
move
(
tensor
)),
_index
(
index
),
_net_flag
(
net_flag
)
{}
const
float
*
get_float_data
()
const
;
const
int
*
get_int_data
()
const
;
int64_t
get_size
()
const
;
const
std
::
vector
<
std
::
vector
<
uint64_t
>>
get_lod
()
const
;
const
std
::
vector
<
int64_t
>
get_shape
()
const
;
std
::
vector
<
float
>
data
;
// return float, or use data_int
std
::
vector
<
int
>
data_int
;
// several layers return int ,or use data
std
::
vector
<
int64_t
>
shape
;
// PaddleLite output shape
std
::
vector
<
std
::
vector
<
uint64_t
>>
lod
;
// PaddleLite output lod
private:
std
::
unique_ptr
<
const
paddle
::
lite_api
::
Tensor
>
_tensor
;
int
_index
;
int
_net_flag
;
};
}
deploy/android_demo/app/src/main/cpp/preprocess.cpp
0 → 100644
View file @
19eb7eb8
#include "preprocess.h"
#include <android/bitmap.h>
cv
::
Mat
bitmap_to_cv_mat
(
JNIEnv
*
env
,
jobject
bitmap
)
{
AndroidBitmapInfo
info
;
int
result
=
AndroidBitmap_getInfo
(
env
,
bitmap
,
&
info
);
if
(
result
!=
ANDROID_BITMAP_RESULT_SUCCESS
)
{
LOGE
(
"AndroidBitmap_getInfo failed, result: %d"
,
result
);
return
cv
::
Mat
{};
}
if
(
info
.
format
!=
ANDROID_BITMAP_FORMAT_RGBA_8888
)
{
LOGE
(
"Bitmap format is not RGBA_8888 !"
);
return
cv
::
Mat
{};
}
unsigned
char
*
srcData
=
NULL
;
AndroidBitmap_lockPixels
(
env
,
bitmap
,
(
void
**
)
&
srcData
);
cv
::
Mat
mat
=
cv
::
Mat
::
zeros
(
info
.
height
,
info
.
width
,
CV_8UC4
);
memcpy
(
mat
.
data
,
srcData
,
info
.
height
*
info
.
width
*
4
);
AndroidBitmap_unlockPixels
(
env
,
bitmap
);
cv
::
cvtColor
(
mat
,
mat
,
cv
::
COLOR_RGBA2BGR
);
/**
if (!cv::imwrite("/sdcard/1/copy.jpg", mat)){
LOGE("Write image failed " );
}
*/
return
mat
;
}
cv
::
Mat
resize_img
(
const
cv
::
Mat
&
img
,
int
height
,
int
width
)
{
if
(
img
.
rows
==
height
&&
img
.
cols
==
width
)
{
return
img
;
}
cv
::
Mat
new_img
;
cv
::
resize
(
img
,
new_img
,
cv
::
Size
(
height
,
width
));
return
new_img
;
}
// fill tensor with mean and scale and trans layout: nhwc -> nchw, neon speed up
void
neon_mean_scale
(
const
float
*
din
,
float
*
dout
,
int
size
,
const
std
::
vector
<
float
>
&
mean
,
const
std
::
vector
<
float
>
&
scale
)
{
if
(
mean
.
size
()
!=
3
||
scale
.
size
()
!=
3
)
{
LOGE
(
"[ERROR] mean or scale size must equal to 3"
);
return
;
}
float32x4_t
vmean0
=
vdupq_n_f32
(
mean
[
0
]);
float32x4_t
vmean1
=
vdupq_n_f32
(
mean
[
1
]);
float32x4_t
vmean2
=
vdupq_n_f32
(
mean
[
2
]);
float32x4_t
vscale0
=
vdupq_n_f32
(
scale
[
0
]);
float32x4_t
vscale1
=
vdupq_n_f32
(
scale
[
1
]);
float32x4_t
vscale2
=
vdupq_n_f32
(
scale
[
2
]);
float
*
dout_c0
=
dout
;
float
*
dout_c1
=
dout
+
size
;
float
*
dout_c2
=
dout
+
size
*
2
;
int
i
=
0
;
for
(;
i
<
size
-
3
;
i
+=
4
)
{
float32x4x3_t
vin3
=
vld3q_f32
(
din
);
float32x4_t
vsub0
=
vsubq_f32
(
vin3
.
val
[
0
],
vmean0
);
float32x4_t
vsub1
=
vsubq_f32
(
vin3
.
val
[
1
],
vmean1
);
float32x4_t
vsub2
=
vsubq_f32
(
vin3
.
val
[
2
],
vmean2
);
float32x4_t
vs0
=
vmulq_f32
(
vsub0
,
vscale0
);
float32x4_t
vs1
=
vmulq_f32
(
vsub1
,
vscale1
);
float32x4_t
vs2
=
vmulq_f32
(
vsub2
,
vscale2
);
vst1q_f32
(
dout_c0
,
vs0
);
vst1q_f32
(
dout_c1
,
vs1
);
vst1q_f32
(
dout_c2
,
vs2
);
din
+=
12
;
dout_c0
+=
4
;
dout_c1
+=
4
;
dout_c2
+=
4
;
}
for
(;
i
<
size
;
i
++
)
{
*
(
dout_c0
++
)
=
(
*
(
din
++
)
-
mean
[
0
])
*
scale
[
0
];
*
(
dout_c1
++
)
=
(
*
(
din
++
)
-
mean
[
1
])
*
scale
[
1
];
*
(
dout_c2
++
)
=
(
*
(
din
++
)
-
mean
[
2
])
*
scale
[
2
];
}
}
\ No newline at end of file
deploy/android_demo/app/src/main/cpp/preprocess.h
0 → 100644
View file @
19eb7eb8
#pragma once
#include "common.h"
#include <jni.h>
#include <opencv2/opencv.hpp>
cv
::
Mat
bitmap_to_cv_mat
(
JNIEnv
*
env
,
jobject
bitmap
);
cv
::
Mat
resize_img
(
const
cv
::
Mat
&
img
,
int
height
,
int
width
);
void
neon_mean_scale
(
const
float
*
din
,
float
*
dout
,
int
size
,
const
std
::
vector
<
float
>
&
mean
,
const
std
::
vector
<
float
>
&
scale
);
deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/AppCompatPreferenceActivity.java
0 → 100644
View file @
19eb7eb8
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com.baidu.paddle.lite.demo.ocr
;
import
android.content.res.Configuration
;
import
android.os.Bundle
;
import
android.preference.PreferenceActivity
;
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.
* <p>
* This technique can be used with an {@link android.app.Activity} class, not just
* {@link PreferenceActivity}.
*/
public
abstract
class
AppCompatPreferenceActivity
extends
PreferenceActivity
{
private
AppCompatDelegate
mDelegate
;
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
getDelegate
().
installViewFactory
();
getDelegate
().
onCreate
(
savedInstanceState
);
super
.
onCreate
(
savedInstanceState
);
}
@Override
protected
void
onPostCreate
(
Bundle
savedInstanceState
)
{
super
.
onPostCreate
(
savedInstanceState
);
getDelegate
().
onPostCreate
(
savedInstanceState
);
}
public
ActionBar
getSupportActionBar
()
{
return
getDelegate
().
getSupportActionBar
();
}
public
void
setSupportActionBar
(
@Nullable
Toolbar
toolbar
)
{
getDelegate
().
setSupportActionBar
(
toolbar
);
}
@Override
public
MenuInflater
getMenuInflater
()
{
return
getDelegate
().
getMenuInflater
();
}
@Override
public
void
setContentView
(
@LayoutRes
int
layoutResID
)
{
getDelegate
().
setContentView
(
layoutResID
);
}
@Override
public
void
setContentView
(
View
view
)
{
getDelegate
().
setContentView
(
view
);
}
@Override
public
void
setContentView
(
View
view
,
ViewGroup
.
LayoutParams
params
)
{
getDelegate
().
setContentView
(
view
,
params
);
}
@Override
public
void
addContentView
(
View
view
,
ViewGroup
.
LayoutParams
params
)
{
getDelegate
().
addContentView
(
view
,
params
);
}
@Override
protected
void
onPostResume
()
{
super
.
onPostResume
();
getDelegate
().
onPostResume
();
}
@Override
protected
void
onTitleChanged
(
CharSequence
title
,
int
color
)
{
super
.
onTitleChanged
(
title
,
color
);
getDelegate
().
setTitle
(
title
);
}
@Override
public
void
onConfigurationChanged
(
Configuration
newConfig
)
{
super
.
onConfigurationChanged
(
newConfig
);
getDelegate
().
onConfigurationChanged
(
newConfig
);
}
@Override
protected
void
onStop
()
{
super
.
onStop
();
getDelegate
().
onStop
();
}
@Override
protected
void
onDestroy
()
{
super
.
onDestroy
();
getDelegate
().
onDestroy
();
}
public
void
invalidateOptionsMenu
()
{
getDelegate
().
invalidateOptionsMenu
();
}
private
AppCompatDelegate
getDelegate
()
{
if
(
mDelegate
==
null
)
{
mDelegate
=
AppCompatDelegate
.
create
(
this
,
null
);
}
return
mDelegate
;
}
}
deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/MainActivity.java
0 → 100644
View file @
19eb7eb8
package
com.baidu.paddle.lite.demo.ocr
;
import
android.Manifest
;
import
android.app.ProgressDialog
;
import
android.content.ContentResolver
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.content.SharedPreferences
;
import
android.content.pm.PackageManager
;
import
android.database.Cursor
;
import
android.graphics.Bitmap
;
import
android.graphics.BitmapFactory
;
import
android.graphics.drawable.BitmapDrawable
;
import
android.media.ExifInterface
;
import
android.content.res.AssetManager
;
import
android.net.Uri
;
import
android.os.Bundle
;
import
android.os.Environment
;
import
android.os.Handler
;
import
android.os.HandlerThread
;
import
android.os.Message
;
import
android.preference.PreferenceManager
;
import
android.provider.MediaStore
;
import
android.text.method.ScrollingMovementMethod
;
import
android.util.Log
;
import
android.view.Menu
;
import
android.view.MenuInflater
;
import
android.view.MenuItem
;
import
android.view.View
;
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
;
import
java.text.SimpleDateFormat
;
import
java.util.Date
;
public
class
MainActivity
extends
AppCompatActivity
{
private
static
final
String
TAG
=
MainActivity
.
class
.
getSimpleName
();
public
static
final
int
OPEN_GALLERY_REQUEST_CODE
=
0
;
public
static
final
int
TAKE_PHOTO_REQUEST_CODE
=
1
;
public
static
final
int
REQUEST_LOAD_MODEL
=
0
;
public
static
final
int
REQUEST_RUN_MODEL
=
1
;
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
;
protected
ProgressDialog
pbLoadModel
=
null
;
protected
ProgressDialog
pbRunModel
=
null
;
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
// UI components of object detection
protected
TextView
tvInputSetting
;
protected
TextView
tvStatus
;
protected
ImageView
ivInputImage
;
protected
TextView
tvOutputResult
;
protected
TextView
tvInferenceTime
;
// Model settings of object detection
protected
String
modelPath
=
""
;
protected
String
labelPath
=
""
;
protected
String
imagePath
=
""
;
protected
int
cpuThreadNum
=
1
;
protected
String
cpuPowerMode
=
""
;
protected
String
inputColorFormat
=
""
;
protected
long
[]
inputShape
=
new
long
[]{};
protected
float
[]
inputMean
=
new
float
[]{};
protected
float
[]
inputStd
=
new
float
[]{};
protected
float
scoreThreshold
=
0.1f
;
private
String
currentPhotoPath
;
private
AssetManager
assetManager
=
null
;
protected
Predictor
predictor
=
new
Predictor
();
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
setContentView
(
R
.
layout
.
activity_main
);
// Clear all setting items to avoid app crashing due to the incorrect settings
SharedPreferences
sharedPreferences
=
PreferenceManager
.
getDefaultSharedPreferences
(
this
);
SharedPreferences
.
Editor
editor
=
sharedPreferences
.
edit
();
editor
.
clear
();
editor
.
apply
();
// Setup the UI components
tvInputSetting
=
findViewById
(
R
.
id
.
tv_input_setting
);
tvStatus
=
findViewById
(
R
.
id
.
tv_model_img_status
);
ivInputImage
=
findViewById
(
R
.
id
.
iv_input_image
);
tvInferenceTime
=
findViewById
(
R
.
id
.
tv_inference_time
);
tvOutputResult
=
findViewById
(
R
.
id
.
tv_output_result
);
tvInputSetting
.
setMovementMethod
(
ScrollingMovementMethod
.
getInstance
());
tvOutputResult
.
setMovementMethod
(
ScrollingMovementMethod
.
getInstance
());
// Prepare the worker thread for mode loading and inference
receiver
=
new
Handler
()
{
@Override
public
void
handleMessage
(
Message
msg
)
{
switch
(
msg
.
what
)
{
case
RESPONSE_LOAD_MODEL_SUCCESSED:
if
(
pbLoadModel
!=
null
&&
pbLoadModel
.
isShowing
()){
pbLoadModel
.
dismiss
();
}
onLoadModelSuccessed
();
break
;
case
RESPONSE_LOAD_MODEL_FAILED:
if
(
pbLoadModel
!=
null
&&
pbLoadModel
.
isShowing
()){
pbLoadModel
.
dismiss
();
}
Toast
.
makeText
(
MainActivity
.
this
,
"Load model failed!"
,
Toast
.
LENGTH_SHORT
).
show
();
onLoadModelFailed
();
break
;
case
RESPONSE_RUN_MODEL_SUCCESSED:
if
(
pbRunModel
!=
null
&&
pbRunModel
.
isShowing
()){
pbRunModel
.
dismiss
();
}
onRunModelSuccessed
();
break
;
case
RESPONSE_RUN_MODEL_FAILED:
if
(
pbRunModel
!=
null
&&
pbRunModel
.
isShowing
()){
pbRunModel
.
dismiss
();
}
Toast
.
makeText
(
MainActivity
.
this
,
"Run model failed!"
,
Toast
.
LENGTH_SHORT
).
show
();
onRunModelFailed
();
break
;
default
:
break
;
}
}
};
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
())
{
receiver
.
sendEmptyMessage
(
RESPONSE_LOAD_MODEL_SUCCESSED
);
}
else
{
receiver
.
sendEmptyMessage
(
RESPONSE_LOAD_MODEL_FAILED
);
}
break
;
case
REQUEST_RUN_MODEL:
// Run model if model is loaded
if
(
onRunModel
())
{
receiver
.
sendEmptyMessage
(
RESPONSE_RUN_MODEL_SUCCESSED
);
}
else
{
receiver
.
sendEmptyMessage
(
RESPONSE_RUN_MODEL_FAILED
);
}
break
;
default
:
break
;
}
}
};
}
@Override
protected
void
onResume
()
{
super
.
onResume
();
SharedPreferences
sharedPreferences
=
PreferenceManager
.
getDefaultSharedPreferences
(
this
);
boolean
settingsChanged
=
false
;
String
model_path
=
sharedPreferences
.
getString
(
getString
(
R
.
string
.
MODEL_PATH_KEY
),
getString
(
R
.
string
.
MODEL_PATH_DEFAULT
));
String
label_path
=
sharedPreferences
.
getString
(
getString
(
R
.
string
.
LABEL_PATH_KEY
),
getString
(
R
.
string
.
LABEL_PATH_DEFAULT
));
String
image_path
=
sharedPreferences
.
getString
(
getString
(
R
.
string
.
IMAGE_PATH_KEY
),
getString
(
R
.
string
.
IMAGE_PATH_DEFAULT
));
settingsChanged
|=
!
model_path
.
equalsIgnoreCase
(
modelPath
);
settingsChanged
|=
!
label_path
.
equalsIgnoreCase
(
labelPath
);
settingsChanged
|=
!
image_path
.
equalsIgnoreCase
(
imagePath
);
int
cpu_thread_num
=
Integer
.
parseInt
(
sharedPreferences
.
getString
(
getString
(
R
.
string
.
CPU_THREAD_NUM_KEY
),
getString
(
R
.
string
.
CPU_THREAD_NUM_DEFAULT
)));
settingsChanged
|=
cpu_thread_num
!=
cpuThreadNum
;
String
cpu_power_mode
=
sharedPreferences
.
getString
(
getString
(
R
.
string
.
CPU_POWER_MODE_KEY
),
getString
(
R
.
string
.
CPU_POWER_MODE_DEFAULT
));
settingsChanged
|=
!
cpu_power_mode
.
equalsIgnoreCase
(
cpuPowerMode
);
String
input_color_format
=
sharedPreferences
.
getString
(
getString
(
R
.
string
.
INPUT_COLOR_FORMAT_KEY
),
getString
(
R
.
string
.
INPUT_COLOR_FORMAT_DEFAULT
));
settingsChanged
|=
!
input_color_format
.
equalsIgnoreCase
(
inputColorFormat
);
long
[]
input_shape
=
Utils
.
parseLongsFromString
(
sharedPreferences
.
getString
(
getString
(
R
.
string
.
INPUT_SHAPE_KEY
),
getString
(
R
.
string
.
INPUT_SHAPE_DEFAULT
)),
","
);
float
[]
input_mean
=
Utils
.
parseFloatsFromString
(
sharedPreferences
.
getString
(
getString
(
R
.
string
.
INPUT_MEAN_KEY
),
getString
(
R
.
string
.
INPUT_MEAN_DEFAULT
)),
","
);
float
[]
input_std
=
Utils
.
parseFloatsFromString
(
sharedPreferences
.
getString
(
getString
(
R
.
string
.
INPUT_STD_KEY
)
,
getString
(
R
.
string
.
INPUT_STD_DEFAULT
)),
","
);
settingsChanged
|=
input_shape
.
length
!=
inputShape
.
length
;
settingsChanged
|=
input_mean
.
length
!=
inputMean
.
length
;
settingsChanged
|=
input_std
.
length
!=
inputStd
.
length
;
if
(!
settingsChanged
)
{
for
(
int
i
=
0
;
i
<
input_shape
.
length
;
i
++)
{
settingsChanged
|=
input_shape
[
i
]
!=
inputShape
[
i
];
}
for
(
int
i
=
0
;
i
<
input_mean
.
length
;
i
++)
{
settingsChanged
|=
input_mean
[
i
]
!=
inputMean
[
i
];
}
for
(
int
i
=
0
;
i
<
input_std
.
length
;
i
++)
{
settingsChanged
|=
input_std
[
i
]
!=
inputStd
[
i
];
}
}
float
score_threshold
=
Float
.
parseFloat
(
sharedPreferences
.
getString
(
getString
(
R
.
string
.
SCORE_THRESHOLD_KEY
),
getString
(
R
.
string
.
SCORE_THRESHOLD_DEFAULT
)));
settingsChanged
|=
scoreThreshold
!=
score_threshold
;
if
(
settingsChanged
)
{
modelPath
=
model_path
;
labelPath
=
label_path
;
imagePath
=
image_path
;
cpuThreadNum
=
cpu_thread_num
;
cpuPowerMode
=
cpu_power_mode
;
inputColorFormat
=
input_color_format
;
inputShape
=
input_shape
;
inputMean
=
input_mean
;
inputStd
=
input_std
;
scoreThreshold
=
score_threshold
;
// Update UI
tvInputSetting
.
setText
(
"Model: "
+
modelPath
.
substring
(
modelPath
.
lastIndexOf
(
"/"
)
+
1
)
+
"\n"
+
"CPU"
+
" Thread Num: "
+
Integer
.
toString
(
cpuThreadNum
)
+
"\n"
+
"CPU Power Mode: "
+
cpuPowerMode
);
tvInputSetting
.
scrollTo
(
0
,
0
);
// Reload model if configure has been changed
// loadModel();
set_img
();
}
}
public
void
loadModel
()
{
pbLoadModel
=
ProgressDialog
.
show
(
this
,
""
,
"loading model..."
,
false
,
false
);
sender
.
sendEmptyMessage
(
REQUEST_LOAD_MODEL
);
}
public
void
runModel
()
{
pbRunModel
=
ProgressDialog
.
show
(
this
,
""
,
"running model..."
,
false
,
false
);
sender
.
sendEmptyMessage
(
REQUEST_RUN_MODEL
);
}
public
boolean
onLoadModel
()
{
return
predictor
.
init
(
MainActivity
.
this
,
modelPath
,
labelPath
,
cpuThreadNum
,
cpuPowerMode
,
inputColorFormat
,
inputShape
,
inputMean
,
inputStd
,
scoreThreshold
);
}
public
boolean
onRunModel
()
{
return
predictor
.
isLoaded
()
&&
predictor
.
runModel
();
}
public
void
onLoadModelSuccessed
()
{
// Load test image from path and run model
tvStatus
.
setText
(
"STATUS: load model successed"
);
}
public
void
onLoadModelFailed
()
{
tvStatus
.
setText
(
"STATUS: load model failed"
);
}
public
void
onRunModelSuccessed
()
{
tvStatus
.
setText
(
"STATUS: run model successed"
);
// Obtain results and update UI
tvInferenceTime
.
setText
(
"Inference time: "
+
predictor
.
inferenceTime
()
+
" ms"
);
Bitmap
outputImage
=
predictor
.
outputImage
();
if
(
outputImage
!=
null
)
{
ivInputImage
.
setImageBitmap
(
outputImage
);
}
tvOutputResult
.
setText
(
predictor
.
outputResult
());
tvOutputResult
.
scrollTo
(
0
,
0
);
}
public
void
onRunModelFailed
()
{
tvStatus
.
setText
(
"STATUS: run model failed"
);
}
public
void
onImageChanged
(
Bitmap
image
)
{
// Rerun model if users pick test image from gallery or camera
if
(
image
!=
null
&&
predictor
.
isLoaded
())
{
predictor
.
setInputImage
(
image
);
runModel
();
}
}
public
void
set_img
()
{
// Load test image from path and run model
try
{
assetManager
=
getAssets
();
InputStream
in
=
assetManager
.
open
(
imagePath
);
Bitmap
bmp
=
BitmapFactory
.
decodeStream
(
in
);
ivInputImage
.
setImageBitmap
(
bmp
);
}
catch
(
IOException
e
)
{
Toast
.
makeText
(
MainActivity
.
this
,
"Load image failed!"
,
Toast
.
LENGTH_SHORT
).
show
();
e
.
printStackTrace
();
}
}
public
void
onSettingsClicked
()
{
startActivity
(
new
Intent
(
MainActivity
.
this
,
SettingsActivity
.
class
));
}
@Override
public
boolean
onCreateOptionsMenu
(
Menu
menu
)
{
MenuInflater
inflater
=
getMenuInflater
();
inflater
.
inflate
(
R
.
menu
.
menu_action_options
,
menu
);
return
true
;
}
public
boolean
onPrepareOptionsMenu
(
Menu
menu
)
{
boolean
isLoaded
=
predictor
.
isLoaded
();
return
super
.
onPrepareOptionsMenu
(
menu
);
}
@Override
public
boolean
onOptionsItemSelected
(
MenuItem
item
)
{
switch
(
item
.
getItemId
())
{
case
android
.
R
.
id
.
home
:
finish
();
break
;
case
R
.
id
.
settings
:
if
(
requestAllPermissions
())
{
// Make sure we have SDCard r&w permissions to load model from SDCard
onSettingsClicked
();
}
break
;
}
return
super
.
onOptionsItemSelected
(
item
);
}
@Override
public
void
onRequestPermissionsResult
(
int
requestCode
,
@NonNull
String
[]
permissions
,
@NonNull
int
[]
grantResults
)
{
super
.
onRequestPermissionsResult
(
requestCode
,
permissions
,
grantResults
);
if
(
grantResults
[
0
]
!=
PackageManager
.
PERMISSION_GRANTED
||
grantResults
[
1
]
!=
PackageManager
.
PERMISSION_GRANTED
)
{
Toast
.
makeText
(
this
,
"Permission Denied"
,
Toast
.
LENGTH_SHORT
).
show
();
}
}
private
boolean
requestAllPermissions
()
{
if
(
ContextCompat
.
checkSelfPermission
(
this
,
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
)
!=
PackageManager
.
PERMISSION_GRANTED
||
ContextCompat
.
checkSelfPermission
(
this
,
Manifest
.
permission
.
CAMERA
)
!=
PackageManager
.
PERMISSION_GRANTED
)
{
ActivityCompat
.
requestPermissions
(
this
,
new
String
[]{
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
,
Manifest
.
permission
.
CAMERA
},
0
);
return
false
;
}
return
true
;
}
private
void
openGallery
()
{
Intent
intent
=
new
Intent
(
Intent
.
ACTION_PICK
,
null
);
intent
.
setDataAndType
(
MediaStore
.
Images
.
Media
.
EXTERNAL_CONTENT_URI
,
"image/*"
);
startActivityForResult
(
intent
,
OPEN_GALLERY_REQUEST_CODE
);
}
private
void
takePhoto
()
{
Intent
takePictureIntent
=
new
Intent
(
MediaStore
.
ACTION_IMAGE_CAPTURE
);
// Ensure that there's a camera activity to handle the intent
if
(
takePictureIntent
.
resolveActivity
(
getPackageManager
())
!=
null
)
{
// Create the File where the photo should go
File
photoFile
=
null
;
try
{
photoFile
=
createImageFile
();
}
catch
(
IOException
ex
)
{
Log
.
e
(
"MainActitity"
,
ex
.
getMessage
(),
ex
);
Toast
.
makeText
(
MainActivity
.
this
,
"Create Camera temp file failed: "
+
ex
.
getMessage
(),
Toast
.
LENGTH_SHORT
).
show
();
}
// Continue only if the File was successfully created
if
(
photoFile
!=
null
)
{
Log
.
i
(
TAG
,
"FILEPATH "
+
getExternalFilesDir
(
"Pictures"
).
getAbsolutePath
());
Uri
photoURI
=
FileProvider
.
getUriForFile
(
this
,
"com.baidu.paddle.lite.demo.ocr.fileprovider"
,
photoFile
);
currentPhotoPath
=
photoFile
.
getAbsolutePath
();
takePictureIntent
.
putExtra
(
MediaStore
.
EXTRA_OUTPUT
,
photoURI
);
startActivityForResult
(
takePictureIntent
,
TAKE_PHOTO_REQUEST_CODE
);
Log
.
i
(
TAG
,
"startActivityForResult finished"
);
}
}
}
private
File
createImageFile
()
throws
IOException
{
// Create an image file name
String
timeStamp
=
new
SimpleDateFormat
(
"yyyyMMdd_HHmmss"
).
format
(
new
Date
());
String
imageFileName
=
"JPEG_"
+
timeStamp
+
"_"
;
File
storageDir
=
getExternalFilesDir
(
Environment
.
DIRECTORY_PICTURES
);
File
image
=
File
.
createTempFile
(
imageFileName
,
/* prefix */
".bmp"
,
/* suffix */
storageDir
/* directory */
);
return
image
;
}
@Override
protected
void
onActivityResult
(
int
requestCode
,
int
resultCode
,
Intent
data
)
{
super
.
onActivityResult
(
requestCode
,
resultCode
,
data
);
if
(
resultCode
==
RESULT_OK
)
{
switch
(
requestCode
)
{
case
OPEN_GALLERY_REQUEST_CODE:
if
(
data
==
null
)
{
break
;
}
try
{
ContentResolver
resolver
=
getContentResolver
();
Uri
uri
=
data
.
getData
();
Bitmap
image
=
MediaStore
.
Images
.
Media
.
getBitmap
(
resolver
,
uri
);
String
[]
proj
=
{
MediaStore
.
Images
.
Media
.
DATA
};
Cursor
cursor
=
managedQuery
(
uri
,
proj
,
null
,
null
,
null
);
cursor
.
moveToFirst
();
if
(
image
!=
null
)
{
// onImageChanged(image);
ivInputImage
.
setImageBitmap
(
image
);
}
}
catch
(
IOException
e
)
{
Log
.
e
(
TAG
,
e
.
toString
());
}
break
;
case
TAKE_PHOTO_REQUEST_CODE:
if
(
currentPhotoPath
!=
null
)
{
ExifInterface
exif
=
null
;
try
{
exif
=
new
ExifInterface
(
currentPhotoPath
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
int
orientation
=
exif
.
getAttributeInt
(
ExifInterface
.
TAG_ORIENTATION
,
ExifInterface
.
ORIENTATION_UNDEFINED
);
Log
.
i
(
TAG
,
"rotation "
+
orientation
);
Bitmap
image
=
BitmapFactory
.
decodeFile
(
currentPhotoPath
);
image
=
Utils
.
rotateBitmap
(
image
,
orientation
);
if
(
image
!=
null
)
{
// onImageChanged(image);
ivInputImage
.
setImageBitmap
(
image
);
}
}
else
{
Log
.
e
(
TAG
,
"currentPhotoPath is null"
);
}
break
;
default
:
break
;
}
}
}
public
void
btn_load_model_click
(
View
view
)
{
if
(
predictor
.
isLoaded
()){
tvStatus
.
setText
(
"STATUS: model has been loaded"
);
}
else
{
tvStatus
.
setText
(
"STATUS: load model ......"
);
loadModel
();
}
}
public
void
btn_run_model_click
(
View
view
)
{
Bitmap
image
=((
BitmapDrawable
)
ivInputImage
.
getDrawable
()).
getBitmap
();
if
(
image
==
null
)
{
tvStatus
.
setText
(
"STATUS: image is not exists"
);
}
else
if
(!
predictor
.
isLoaded
()){
tvStatus
.
setText
(
"STATUS: model is not loaded"
);
}
else
{
tvStatus
.
setText
(
"STATUS: run model ...... "
);
predictor
.
setInputImage
(
image
);
runModel
();
}
}
public
void
btn_choice_img_click
(
View
view
)
{
if
(
requestAllPermissions
())
{
openGallery
();
}
}
public
void
btn_take_photo_click
(
View
view
)
{
if
(
requestAllPermissions
())
{
takePhoto
();
}
}
@Override
protected
void
onDestroy
()
{
if
(
predictor
!=
null
)
{
predictor
.
releaseModel
();
}
worker
.
quit
();
super
.
onDestroy
();
}
}
deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/MiniActivity.java
0 → 100644
View file @
19eb7eb8
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_v2_for_cpu"
;
private
String
assetlabelFilePath
=
"labels/ppocr_keys_v1.txt"
;
private
Button
button
;
private
ImageView
imageView
;
// image result
private
TextView
textView
;
// text result
@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
);
// corresponding to REQUEST_LOAD_MODEL, to call 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
();
}
/**
* call in onCreate, model init
*
* @return
*/
private
boolean
onLoadModel
()
{
if
(
predictor
==
null
)
{
predictor
=
new
Predictor
();
}
return
predictor
.
init
(
this
,
assetModelDirPath
,
assetlabelFilePath
);
}
/**
* init engine
* call in onCreate
*
* @return
*/
private
boolean
onRunModel
()
{
try
{
String
assetImagePath
=
"images/0.jpg"
;
InputStream
imageStream
=
getAssets
().
open
(
assetImagePath
);
Bitmap
image
=
BitmapFactory
.
decodeStream
(
imageStream
);
// Input is 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
();
}
}
}
deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/OCRPredictorNative.java
0 → 100644
View file @
19eb7eb8
package
com.baidu.paddle.lite.demo.ocr
;
import
android.graphics.Bitmap
;
import
android.util.Log
;
import
java.util.ArrayList
;
import
java.util.concurrent.atomic.AtomicBoolean
;
public
class
OCRPredictorNative
{
private
static
final
AtomicBoolean
isSOLoaded
=
new
AtomicBoolean
();
public
static
void
loadLibrary
()
throws
RuntimeException
{
if
(!
isSOLoaded
.
get
()
&&
isSOLoaded
.
compareAndSet
(
false
,
true
))
{
try
{
System
.
loadLibrary
(
"Native"
);
}
catch
(
Throwable
e
)
{
RuntimeException
exception
=
new
RuntimeException
(
"Load libNative.so failed, please check it exists in apk file."
,
e
);
throw
exception
;
}
}
}
private
Config
config
;
private
long
nativePointer
=
0
;
public
OCRPredictorNative
(
Config
config
)
{
this
.
config
=
config
;
loadLibrary
();
nativePointer
=
init
(
config
.
detModelFilename
,
config
.
recModelFilename
,
config
.
clsModelFilename
,
config
.
cpuThreadNum
,
config
.
cpuPower
);
Log
.
i
(
"OCRPredictorNative"
,
"load success "
+
nativePointer
);
}
public
ArrayList
<
OcrResultModel
>
runImage
(
float
[]
inputData
,
int
width
,
int
height
,
int
channels
,
Bitmap
originalImage
)
{
Log
.
i
(
"OCRPredictorNative"
,
"begin to run image "
+
inputData
.
length
+
" "
+
width
+
" "
+
height
);
float
[]
dims
=
new
float
[]{
1
,
channels
,
height
,
width
};
float
[]
rawResults
=
forward
(
nativePointer
,
inputData
,
dims
,
originalImage
);
ArrayList
<
OcrResultModel
>
results
=
postprocess
(
rawResults
);
return
results
;
}
public
static
class
Config
{
public
int
cpuThreadNum
;
public
String
cpuPower
;
public
String
detModelFilename
;
public
String
recModelFilename
;
public
String
clsModelFilename
;
}
public
void
destory
(){
if
(
nativePointer
>
0
)
{
release
(
nativePointer
);
nativePointer
=
0
;
}
}
protected
native
long
init
(
String
detModelPath
,
String
recModelPath
,
String
clsModelPath
,
int
threadNum
,
String
cpuMode
);
protected
native
float
[]
forward
(
long
pointer
,
float
[]
buf
,
float
[]
ddims
,
Bitmap
originalImage
);
protected
native
void
release
(
long
pointer
);
private
ArrayList
<
OcrResultModel
>
postprocess
(
float
[]
raw
)
{
ArrayList
<
OcrResultModel
>
results
=
new
ArrayList
<
OcrResultModel
>();
int
begin
=
0
;
while
(
begin
<
raw
.
length
)
{
int
point_num
=
Math
.
round
(
raw
[
begin
]);
int
word_num
=
Math
.
round
(
raw
[
begin
+
1
]);
OcrResultModel
model
=
parse
(
raw
,
begin
+
2
,
point_num
,
word_num
);
begin
+=
2
+
1
+
point_num
*
2
+
word_num
;
results
.
add
(
model
);
}
return
results
;
}
private
OcrResultModel
parse
(
float
[]
raw
,
int
begin
,
int
pointNum
,
int
wordNum
)
{
int
current
=
begin
;
OcrResultModel
model
=
new
OcrResultModel
();
model
.
setConfidence
(
raw
[
current
]);
current
++;
for
(
int
i
=
0
;
i
<
pointNum
;
i
++)
{
model
.
addPoints
(
Math
.
round
(
raw
[
current
+
i
*
2
]),
Math
.
round
(
raw
[
current
+
i
*
2
+
1
]));
}
current
+=
(
pointNum
*
2
);
for
(
int
i
=
0
;
i
<
wordNum
;
i
++)
{
int
index
=
Math
.
round
(
raw
[
current
+
i
]);
model
.
addWordIndex
(
index
);
}
Log
.
i
(
"OCRPredictorNative"
,
"word finished "
+
wordNum
);
return
model
;
}
}
deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/OcrResultModel.java
0 → 100644
View file @
19eb7eb8
package
com.baidu.paddle.lite.demo.ocr
;
import
android.graphics.Point
;
import
java.util.ArrayList
;
import
java.util.List
;
public
class
OcrResultModel
{
private
List
<
Point
>
points
;
private
List
<
Integer
>
wordIndex
;
private
String
label
;
private
float
confidence
;
public
OcrResultModel
()
{
super
();
points
=
new
ArrayList
<>();
wordIndex
=
new
ArrayList
<>();
}
public
void
addPoints
(
int
x
,
int
y
)
{
Point
point
=
new
Point
(
x
,
y
);
points
.
add
(
point
);
}
public
void
addWordIndex
(
int
index
)
{
wordIndex
.
add
(
index
);
}
public
List
<
Point
>
getPoints
()
{
return
points
;
}
public
List
<
Integer
>
getWordIndex
()
{
return
wordIndex
;
}
public
String
getLabel
()
{
return
label
;
}
public
void
setLabel
(
String
label
)
{
this
.
label
=
label
;
}
public
float
getConfidence
()
{
return
confidence
;
}
public
void
setConfidence
(
float
confidence
)
{
this
.
confidence
=
confidence
;
}
}
deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/Predictor.java
0 → 100644
View file @
19eb7eb8
package
com.baidu.paddle.lite.demo.ocr
;
import
android.content.Context
;
import
android.graphics.Bitmap
;
import
android.graphics.Canvas
;
import
android.graphics.Color
;
import
android.graphics.Paint
;
import
android.graphics.Path
;
import
android.graphics.Point
;
import
android.util.Log
;
import
java.io.File
;
import
java.io.InputStream
;
import
java.util.ArrayList
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Vector
;
import
static
android
.
graphics
.
Color
.*;
public
class
Predictor
{
private
static
final
String
TAG
=
Predictor
.
class
.
getSimpleName
();
public
boolean
isLoaded
=
false
;
public
int
warmupIterNum
=
1
;
public
int
inferIterNum
=
1
;
public
int
cpuThreadNum
=
4
;
public
String
cpuPowerMode
=
"LITE_POWER_HIGH"
;
public
String
modelPath
=
""
;
public
String
modelName
=
""
;
protected
OCRPredictorNative
paddlePredictor
=
null
;
protected
float
inferenceTime
=
0
;
// Only for object detection
protected
Vector
<
String
>
wordLabels
=
new
Vector
<
String
>();
protected
String
inputColorFormat
=
"BGR"
;
protected
long
[]
inputShape
=
new
long
[]{
1
,
3
,
960
};
protected
float
[]
inputMean
=
new
float
[]{
0.485f
,
0.456f
,
0.406f
};
protected
float
[]
inputStd
=
new
float
[]{
1.0f
/
0.229f
,
1.0f
/
0.224f
,
1.0f
/
0.225f
};
protected
float
scoreThreshold
=
0.1f
;
protected
Bitmap
inputImage
=
null
;
protected
Bitmap
outputImage
=
null
;
protected
volatile
String
outputResult
=
""
;
protected
float
preprocessTime
=
0
;
protected
float
postprocessTime
=
0
;
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
,
float
[]
inputStd
,
float
scoreThreshold
)
{
if
(
inputShape
.
length
!=
3
)
{
Log
.
e
(
TAG
,
"Size of input shape should be: 3"
);
return
false
;
}
if
(
inputMean
.
length
!=
inputShape
[
1
])
{
Log
.
e
(
TAG
,
"Size of input mean should be: "
+
Long
.
toString
(
inputShape
[
1
]));
return
false
;
}
if
(
inputStd
.
length
!=
inputShape
[
1
])
{
Log
.
e
(
TAG
,
"Size of input std should be: "
+
Long
.
toString
(
inputShape
[
1
]));
return
false
;
}
if
(
inputShape
[
0
]
!=
1
)
{
Log
.
e
(
TAG
,
"Only one batch is supported in the image classification demo, you can use any batch size in "
+
"your Apps!"
);
return
false
;
}
if
(
inputShape
[
1
]
!=
1
&&
inputShape
[
1
]
!=
3
)
{
Log
.
e
(
TAG
,
"Only one/three channels are supported in the image classification demo, you can use any "
+
"channel size in your Apps!"
);
return
false
;
}
if
(!
inputColorFormat
.
equalsIgnoreCase
(
"BGR"
))
{
Log
.
e
(
TAG
,
"Only BGR color format is supported."
);
return
false
;
}
boolean
isLoaded
=
init
(
appCtx
,
modelPath
,
labelPath
);
if
(!
isLoaded
)
{
return
false
;
}
this
.
inputColorFormat
=
inputColorFormat
;
this
.
inputShape
=
inputShape
;
this
.
inputMean
=
inputMean
;
this
.
inputStd
=
inputStd
;
this
.
scoreThreshold
=
scoreThreshold
;
return
true
;
}
protected
boolean
loadModel
(
Context
appCtx
,
String
modelPath
,
int
cpuThreadNum
,
String
cpuPowerMode
)
{
// Release model if exists
releaseModel
();
// Load model
if
(
modelPath
.
isEmpty
())
{
return
false
;
}
String
realPath
=
modelPath
;
if
(!
modelPath
.
substring
(
0
,
1
).
equals
(
"/"
))
{
// Read model files from custom path if the first character of mode path is '/'
// otherwise copy model to cache from assets
realPath
=
appCtx
.
getCacheDir
()
+
"/"
+
modelPath
;
Utils
.
copyDirectoryFromAssets
(
appCtx
,
modelPath
,
realPath
);
}
if
(
realPath
.
isEmpty
())
{
return
false
;
}
OCRPredictorNative
.
Config
config
=
new
OCRPredictorNative
.
Config
();
config
.
cpuThreadNum
=
cpuThreadNum
;
config
.
detModelFilename
=
realPath
+
File
.
separator
+
"ch_ppocr_mobile_v2.0_det_opt.nb"
;
config
.
recModelFilename
=
realPath
+
File
.
separator
+
"ch_ppocr_mobile_v2.0_rec_opt.nb"
;
config
.
clsModelFilename
=
realPath
+
File
.
separator
+
"ch_ppocr_mobile_v2.0_cls_opt.nb"
;
Log
.
e
(
"Predictor"
,
"model path"
+
config
.
detModelFilename
+
" ; "
+
config
.
recModelFilename
+
";"
+
config
.
clsModelFilename
);
config
.
cpuPower
=
cpuPowerMode
;
paddlePredictor
=
new
OCRPredictorNative
(
config
);
this
.
cpuThreadNum
=
cpuThreadNum
;
this
.
cpuPowerMode
=
cpuPowerMode
;
this
.
modelPath
=
realPath
;
this
.
modelName
=
realPath
.
substring
(
realPath
.
lastIndexOf
(
"/"
)
+
1
);
return
true
;
}
public
void
releaseModel
()
{
if
(
paddlePredictor
!=
null
)
{
paddlePredictor
.
destory
();
paddlePredictor
=
null
;
}
isLoaded
=
false
;
cpuThreadNum
=
1
;
cpuPowerMode
=
"LITE_POWER_HIGH"
;
modelPath
=
""
;
modelName
=
""
;
}
protected
boolean
loadLabel
(
Context
appCtx
,
String
labelPath
)
{
wordLabels
.
clear
();
wordLabels
.
add
(
"black"
);
// Load word labels from file
try
{
InputStream
assetsInputStream
=
appCtx
.
getAssets
().
open
(
labelPath
);
int
available
=
assetsInputStream
.
available
();
byte
[]
lines
=
new
byte
[
available
];
assetsInputStream
.
read
(
lines
);
assetsInputStream
.
close
();
String
words
=
new
String
(
lines
);
String
[]
contents
=
words
.
split
(
"\n"
);
for
(
String
content
:
contents
)
{
wordLabels
.
add
(
content
);
}
Log
.
i
(
TAG
,
"Word label size: "
+
wordLabels
.
size
());
}
catch
(
Exception
e
)
{
Log
.
e
(
TAG
,
e
.
getMessage
());
return
false
;
}
return
true
;
}
public
boolean
runModel
()
{
if
(
inputImage
==
null
||
!
isLoaded
())
{
return
false
;
}
// Pre-process image, and feed input tensor with pre-processed data
Bitmap
scaleImage
=
Utils
.
resizeWithStep
(
inputImage
,
Long
.
valueOf
(
inputShape
[
2
]).
intValue
(),
32
);
Date
start
=
new
Date
();
int
channels
=
(
int
)
inputShape
[
1
];
int
width
=
scaleImage
.
getWidth
();
int
height
=
scaleImage
.
getHeight
();
float
[]
inputData
=
new
float
[
channels
*
width
*
height
];
if
(
channels
==
3
)
{
int
[]
channelIdx
=
null
;
if
(
inputColorFormat
.
equalsIgnoreCase
(
"RGB"
))
{
channelIdx
=
new
int
[]{
0
,
1
,
2
};
}
else
if
(
inputColorFormat
.
equalsIgnoreCase
(
"BGR"
))
{
channelIdx
=
new
int
[]{
2
,
1
,
0
};
}
else
{
Log
.
i
(
TAG
,
"Unknown color format "
+
inputColorFormat
+
", only RGB and BGR color format is "
+
"supported!"
);
return
false
;
}
int
[]
channelStride
=
new
int
[]{
width
*
height
,
width
*
height
*
2
};
int
[]
pixels
=
new
int
[
width
*
height
];
scaleImage
.
getPixels
(
pixels
,
0
,
scaleImage
.
getWidth
(),
0
,
0
,
scaleImage
.
getWidth
(),
scaleImage
.
getHeight
());
for
(
int
i
=
0
;
i
<
pixels
.
length
;
i
++)
{
int
color
=
pixels
[
i
];
float
[]
rgb
=
new
float
[]{(
float
)
red
(
color
)
/
255.0f
,
(
float
)
green
(
color
)
/
255.0f
,
(
float
)
blue
(
color
)
/
255.0f
};
inputData
[
i
]
=
(
rgb
[
channelIdx
[
0
]]
-
inputMean
[
0
])
/
inputStd
[
0
];
inputData
[
i
+
channelStride
[
0
]]
=
(
rgb
[
channelIdx
[
1
]]
-
inputMean
[
1
])
/
inputStd
[
1
];
inputData
[
i
+
channelStride
[
1
]]
=
(
rgb
[
channelIdx
[
2
]]
-
inputMean
[
2
])
/
inputStd
[
2
];
}
}
else
if
(
channels
==
1
)
{
int
[]
pixels
=
new
int
[
width
*
height
];
scaleImage
.
getPixels
(
pixels
,
0
,
scaleImage
.
getWidth
(),
0
,
0
,
scaleImage
.
getWidth
(),
scaleImage
.
getHeight
());
for
(
int
i
=
0
;
i
<
pixels
.
length
;
i
++)
{
int
color
=
pixels
[
i
];
float
gray
=
(
float
)
(
red
(
color
)
+
green
(
color
)
+
blue
(
color
))
/
3.0f
/
255.0f
;
inputData
[
i
]
=
(
gray
-
inputMean
[
0
])
/
inputStd
[
0
];
}
}
else
{
Log
.
i
(
TAG
,
"Unsupported channel size "
+
Integer
.
toString
(
channels
)
+
", only channel 1 and 3 is "
+
"supported!"
);
return
false
;
}
float
[]
pixels
=
inputData
;
Log
.
i
(
TAG
,
"pixels "
+
pixels
[
0
]
+
" "
+
pixels
[
1
]
+
" "
+
pixels
[
2
]
+
" "
+
pixels
[
3
]
+
" "
+
pixels
[
pixels
.
length
/
2
]
+
" "
+
pixels
[
pixels
.
length
/
2
+
1
]
+
" "
+
pixels
[
pixels
.
length
-
2
]
+
" "
+
pixels
[
pixels
.
length
-
1
]);
Date
end
=
new
Date
();
preprocessTime
=
(
float
)
(
end
.
getTime
()
-
start
.
getTime
());
// Warm up
for
(
int
i
=
0
;
i
<
warmupIterNum
;
i
++)
{
paddlePredictor
.
runImage
(
inputData
,
width
,
height
,
channels
,
inputImage
);
}
warmupIterNum
=
0
;
// do not need warm
// Run inference
start
=
new
Date
();
ArrayList
<
OcrResultModel
>
results
=
paddlePredictor
.
runImage
(
inputData
,
width
,
height
,
channels
,
inputImage
);
end
=
new
Date
();
inferenceTime
=
(
end
.
getTime
()
-
start
.
getTime
())
/
(
float
)
inferIterNum
;
results
=
postprocess
(
results
);
Log
.
i
(
TAG
,
"[stat] Preprocess Time: "
+
preprocessTime
+
" ; Inference Time: "
+
inferenceTime
+
" ;Box Size "
+
results
.
size
());
drawResults
(
results
);
return
true
;
}
public
boolean
isLoaded
()
{
return
paddlePredictor
!=
null
&&
isLoaded
;
}
public
String
modelPath
()
{
return
modelPath
;
}
public
String
modelName
()
{
return
modelName
;
}
public
int
cpuThreadNum
()
{
return
cpuThreadNum
;
}
public
String
cpuPowerMode
()
{
return
cpuPowerMode
;
}
public
float
inferenceTime
()
{
return
inferenceTime
;
}
public
Bitmap
inputImage
()
{
return
inputImage
;
}
public
Bitmap
outputImage
()
{
return
outputImage
;
}
public
String
outputResult
()
{
return
outputResult
;
}
public
float
preprocessTime
()
{
return
preprocessTime
;
}
public
float
postprocessTime
()
{
return
postprocessTime
;
}
public
void
setInputImage
(
Bitmap
image
)
{
if
(
image
==
null
)
{
return
;
}
this
.
inputImage
=
image
.
copy
(
Bitmap
.
Config
.
ARGB_8888
,
true
);
}
private
ArrayList
<
OcrResultModel
>
postprocess
(
ArrayList
<
OcrResultModel
>
results
)
{
for
(
OcrResultModel
r
:
results
)
{
StringBuffer
word
=
new
StringBuffer
();
for
(
int
index
:
r
.
getWordIndex
())
{
if
(
index
>=
0
&&
index
<
wordLabels
.
size
())
{
word
.
append
(
wordLabels
.
get
(
index
));
}
else
{
Log
.
e
(
TAG
,
"Word index is not in label list:"
+
index
);
word
.
append
(
"×"
);
}
}
r
.
setLabel
(
word
.
toString
());
}
return
results
;
}
private
void
drawResults
(
ArrayList
<
OcrResultModel
>
results
)
{
StringBuffer
outputResultSb
=
new
StringBuffer
(
""
);
for
(
int
i
=
0
;
i
<
results
.
size
();
i
++)
{
OcrResultModel
result
=
results
.
get
(
i
);
StringBuilder
sb
=
new
StringBuilder
(
""
);
sb
.
append
(
result
.
getLabel
());
sb
.
append
(
" "
).
append
(
result
.
getConfidence
());
sb
.
append
(
"; Points: "
);
for
(
Point
p
:
result
.
getPoints
())
{
sb
.
append
(
"("
).
append
(
p
.
x
).
append
(
","
).
append
(
p
.
y
).
append
(
") "
);
}
Log
.
i
(
TAG
,
sb
.
toString
());
// show LOG in Logcat panel
outputResultSb
.
append
(
i
+
1
).
append
(
": "
).
append
(
result
.
getLabel
()).
append
(
"\n"
);
}
outputResult
=
outputResultSb
.
toString
();
outputImage
=
inputImage
;
Canvas
canvas
=
new
Canvas
(
outputImage
);
Paint
paintFillAlpha
=
new
Paint
();
paintFillAlpha
.
setStyle
(
Paint
.
Style
.
FILL
);
paintFillAlpha
.
setColor
(
Color
.
parseColor
(
"#3B85F5"
));
paintFillAlpha
.
setAlpha
(
50
);
Paint
paint
=
new
Paint
();
paint
.
setColor
(
Color
.
parseColor
(
"#3B85F5"
));
paint
.
setStrokeWidth
(
5
);
paint
.
setStyle
(
Paint
.
Style
.
STROKE
);
for
(
OcrResultModel
result
:
results
)
{
Path
path
=
new
Path
();
List
<
Point
>
points
=
result
.
getPoints
();
path
.
moveTo
(
points
.
get
(
0
).
x
,
points
.
get
(
0
).
y
);
for
(
int
i
=
points
.
size
()
-
1
;
i
>=
0
;
i
--)
{
Point
p
=
points
.
get
(
i
);
path
.
lineTo
(
p
.
x
,
p
.
y
);
}
canvas
.
drawPath
(
path
,
paint
);
canvas
.
drawPath
(
path
,
paintFillAlpha
);
}
}
}
deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/SettingsActivity.java
0 → 100644
View file @
19eb7eb8
package
com.baidu.paddle.lite.demo.ocr
;
import
android.content.SharedPreferences
;
import
android.os.Bundle
;
import
android.preference.CheckBoxPreference
;
import
android.preference.EditTextPreference
;
import
android.preference.ListPreference
;
import
androidx.appcompat.app.ActionBar
;
import
java.util.ArrayList
;
import
java.util.List
;
public
class
SettingsActivity
extends
AppCompatPreferenceActivity
implements
SharedPreferences
.
OnSharedPreferenceChangeListener
{
ListPreference
lpChoosePreInstalledModel
=
null
;
CheckBoxPreference
cbEnableCustomSettings
=
null
;
EditTextPreference
etModelPath
=
null
;
EditTextPreference
etLabelPath
=
null
;
ListPreference
etImagePath
=
null
;
ListPreference
lpCPUThreadNum
=
null
;
ListPreference
lpCPUPowerMode
=
null
;
ListPreference
lpInputColorFormat
=
null
;
EditTextPreference
etInputShape
=
null
;
EditTextPreference
etInputMean
=
null
;
EditTextPreference
etInputStd
=
null
;
EditTextPreference
etScoreThreshold
=
null
;
List
<
String
>
preInstalledModelPaths
=
null
;
List
<
String
>
preInstalledLabelPaths
=
null
;
List
<
String
>
preInstalledImagePaths
=
null
;
List
<
String
>
preInstalledInputShapes
=
null
;
List
<
String
>
preInstalledCPUThreadNums
=
null
;
List
<
String
>
preInstalledCPUPowerModes
=
null
;
List
<
String
>
preInstalledInputColorFormats
=
null
;
List
<
String
>
preInstalledInputMeans
=
null
;
List
<
String
>
preInstalledInputStds
=
null
;
List
<
String
>
preInstalledScoreThresholds
=
null
;
@Override
public
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
addPreferencesFromResource
(
R
.
xml
.
settings
);
ActionBar
supportActionBar
=
getSupportActionBar
();
if
(
supportActionBar
!=
null
)
{
supportActionBar
.
setDisplayHomeAsUpEnabled
(
true
);
}
// Initialized pre-installed models
preInstalledModelPaths
=
new
ArrayList
<
String
>();
preInstalledLabelPaths
=
new
ArrayList
<
String
>();
preInstalledImagePaths
=
new
ArrayList
<
String
>();
preInstalledInputShapes
=
new
ArrayList
<
String
>();
preInstalledCPUThreadNums
=
new
ArrayList
<
String
>();
preInstalledCPUPowerModes
=
new
ArrayList
<
String
>();
preInstalledInputColorFormats
=
new
ArrayList
<
String
>();
preInstalledInputMeans
=
new
ArrayList
<
String
>();
preInstalledInputStds
=
new
ArrayList
<
String
>();
preInstalledScoreThresholds
=
new
ArrayList
<
String
>();
// Add ssd_mobilenet_v1_pascalvoc_for_cpu
preInstalledModelPaths
.
add
(
getString
(
R
.
string
.
MODEL_PATH_DEFAULT
));
preInstalledLabelPaths
.
add
(
getString
(
R
.
string
.
LABEL_PATH_DEFAULT
));
preInstalledImagePaths
.
add
(
getString
(
R
.
string
.
IMAGE_PATH_DEFAULT
));
preInstalledCPUThreadNums
.
add
(
getString
(
R
.
string
.
CPU_THREAD_NUM_DEFAULT
));
preInstalledCPUPowerModes
.
add
(
getString
(
R
.
string
.
CPU_POWER_MODE_DEFAULT
));
preInstalledInputColorFormats
.
add
(
getString
(
R
.
string
.
INPUT_COLOR_FORMAT_DEFAULT
));
preInstalledInputShapes
.
add
(
getString
(
R
.
string
.
INPUT_SHAPE_DEFAULT
));
preInstalledInputMeans
.
add
(
getString
(
R
.
string
.
INPUT_MEAN_DEFAULT
));
preInstalledInputStds
.
add
(
getString
(
R
.
string
.
INPUT_STD_DEFAULT
));
preInstalledScoreThresholds
.
add
(
getString
(
R
.
string
.
SCORE_THRESHOLD_DEFAULT
));
// Setup UI components
lpChoosePreInstalledModel
=
(
ListPreference
)
findPreference
(
getString
(
R
.
string
.
CHOOSE_PRE_INSTALLED_MODEL_KEY
));
String
[]
preInstalledModelNames
=
new
String
[
preInstalledModelPaths
.
size
()];
for
(
int
i
=
0
;
i
<
preInstalledModelPaths
.
size
();
i
++)
{
preInstalledModelNames
[
i
]
=
preInstalledModelPaths
.
get
(
i
).
substring
(
preInstalledModelPaths
.
get
(
i
).
lastIndexOf
(
"/"
)
+
1
);
}
lpChoosePreInstalledModel
.
setEntries
(
preInstalledModelNames
);
lpChoosePreInstalledModel
.
setEntryValues
(
preInstalledModelPaths
.
toArray
(
new
String
[
preInstalledModelPaths
.
size
()]));
cbEnableCustomSettings
=
(
CheckBoxPreference
)
findPreference
(
getString
(
R
.
string
.
ENABLE_CUSTOM_SETTINGS_KEY
));
etModelPath
=
(
EditTextPreference
)
findPreference
(
getString
(
R
.
string
.
MODEL_PATH_KEY
));
etModelPath
.
setTitle
(
"Model Path (SDCard: "
+
Utils
.
getSDCardDirectory
()
+
")"
);
etLabelPath
=
(
EditTextPreference
)
findPreference
(
getString
(
R
.
string
.
LABEL_PATH_KEY
));
etImagePath
=
(
ListPreference
)
findPreference
(
getString
(
R
.
string
.
IMAGE_PATH_KEY
));
lpCPUThreadNum
=
(
ListPreference
)
findPreference
(
getString
(
R
.
string
.
CPU_THREAD_NUM_KEY
));
lpCPUPowerMode
=
(
ListPreference
)
findPreference
(
getString
(
R
.
string
.
CPU_POWER_MODE_KEY
));
lpInputColorFormat
=
(
ListPreference
)
findPreference
(
getString
(
R
.
string
.
INPUT_COLOR_FORMAT_KEY
));
etInputShape
=
(
EditTextPreference
)
findPreference
(
getString
(
R
.
string
.
INPUT_SHAPE_KEY
));
etInputMean
=
(
EditTextPreference
)
findPreference
(
getString
(
R
.
string
.
INPUT_MEAN_KEY
));
etInputStd
=
(
EditTextPreference
)
findPreference
(
getString
(
R
.
string
.
INPUT_STD_KEY
));
etScoreThreshold
=
(
EditTextPreference
)
findPreference
(
getString
(
R
.
string
.
SCORE_THRESHOLD_KEY
));
}
private
void
reloadPreferenceAndUpdateUI
()
{
SharedPreferences
sharedPreferences
=
getPreferenceScreen
().
getSharedPreferences
();
boolean
enableCustomSettings
=
sharedPreferences
.
getBoolean
(
getString
(
R
.
string
.
ENABLE_CUSTOM_SETTINGS_KEY
),
false
);
String
modelPath
=
sharedPreferences
.
getString
(
getString
(
R
.
string
.
CHOOSE_PRE_INSTALLED_MODEL_KEY
),
getString
(
R
.
string
.
MODEL_PATH_DEFAULT
));
int
modelIdx
=
lpChoosePreInstalledModel
.
findIndexOfValue
(
modelPath
);
if
(
modelIdx
>=
0
&&
modelIdx
<
preInstalledModelPaths
.
size
())
{
if
(!
enableCustomSettings
)
{
SharedPreferences
.
Editor
editor
=
sharedPreferences
.
edit
();
editor
.
putString
(
getString
(
R
.
string
.
MODEL_PATH_KEY
),
preInstalledModelPaths
.
get
(
modelIdx
));
editor
.
putString
(
getString
(
R
.
string
.
LABEL_PATH_KEY
),
preInstalledLabelPaths
.
get
(
modelIdx
));
editor
.
putString
(
getString
(
R
.
string
.
IMAGE_PATH_KEY
),
preInstalledImagePaths
.
get
(
modelIdx
));
editor
.
putString
(
getString
(
R
.
string
.
CPU_THREAD_NUM_KEY
),
preInstalledCPUThreadNums
.
get
(
modelIdx
));
editor
.
putString
(
getString
(
R
.
string
.
CPU_POWER_MODE_KEY
),
preInstalledCPUPowerModes
.
get
(
modelIdx
));
editor
.
putString
(
getString
(
R
.
string
.
INPUT_COLOR_FORMAT_KEY
),
preInstalledInputColorFormats
.
get
(
modelIdx
));
editor
.
putString
(
getString
(
R
.
string
.
INPUT_SHAPE_KEY
),
preInstalledInputShapes
.
get
(
modelIdx
));
editor
.
putString
(
getString
(
R
.
string
.
INPUT_MEAN_KEY
),
preInstalledInputMeans
.
get
(
modelIdx
));
editor
.
putString
(
getString
(
R
.
string
.
INPUT_STD_KEY
),
preInstalledInputStds
.
get
(
modelIdx
));
editor
.
putString
(
getString
(
R
.
string
.
SCORE_THRESHOLD_KEY
),
preInstalledScoreThresholds
.
get
(
modelIdx
));
editor
.
apply
();
}
lpChoosePreInstalledModel
.
setSummary
(
modelPath
);
}
cbEnableCustomSettings
.
setChecked
(
enableCustomSettings
);
etModelPath
.
setEnabled
(
enableCustomSettings
);
etLabelPath
.
setEnabled
(
enableCustomSettings
);
etImagePath
.
setEnabled
(
enableCustomSettings
);
lpCPUThreadNum
.
setEnabled
(
enableCustomSettings
);
lpCPUPowerMode
.
setEnabled
(
enableCustomSettings
);
lpInputColorFormat
.
setEnabled
(
enableCustomSettings
);
etInputShape
.
setEnabled
(
enableCustomSettings
);
etInputMean
.
setEnabled
(
enableCustomSettings
);
etInputStd
.
setEnabled
(
enableCustomSettings
);
etScoreThreshold
.
setEnabled
(
enableCustomSettings
);
modelPath
=
sharedPreferences
.
getString
(
getString
(
R
.
string
.
MODEL_PATH_KEY
),
getString
(
R
.
string
.
MODEL_PATH_DEFAULT
));
String
labelPath
=
sharedPreferences
.
getString
(
getString
(
R
.
string
.
LABEL_PATH_KEY
),
getString
(
R
.
string
.
LABEL_PATH_DEFAULT
));
String
imagePath
=
sharedPreferences
.
getString
(
getString
(
R
.
string
.
IMAGE_PATH_KEY
),
getString
(
R
.
string
.
IMAGE_PATH_DEFAULT
));
String
cpuThreadNum
=
sharedPreferences
.
getString
(
getString
(
R
.
string
.
CPU_THREAD_NUM_KEY
),
getString
(
R
.
string
.
CPU_THREAD_NUM_DEFAULT
));
String
cpuPowerMode
=
sharedPreferences
.
getString
(
getString
(
R
.
string
.
CPU_POWER_MODE_KEY
),
getString
(
R
.
string
.
CPU_POWER_MODE_DEFAULT
));
String
inputColorFormat
=
sharedPreferences
.
getString
(
getString
(
R
.
string
.
INPUT_COLOR_FORMAT_KEY
),
getString
(
R
.
string
.
INPUT_COLOR_FORMAT_DEFAULT
));
String
inputShape
=
sharedPreferences
.
getString
(
getString
(
R
.
string
.
INPUT_SHAPE_KEY
),
getString
(
R
.
string
.
INPUT_SHAPE_DEFAULT
));
String
inputMean
=
sharedPreferences
.
getString
(
getString
(
R
.
string
.
INPUT_MEAN_KEY
),
getString
(
R
.
string
.
INPUT_MEAN_DEFAULT
));
String
inputStd
=
sharedPreferences
.
getString
(
getString
(
R
.
string
.
INPUT_STD_KEY
),
getString
(
R
.
string
.
INPUT_STD_DEFAULT
));
String
scoreThreshold
=
sharedPreferences
.
getString
(
getString
(
R
.
string
.
SCORE_THRESHOLD_KEY
),
getString
(
R
.
string
.
SCORE_THRESHOLD_DEFAULT
));
etModelPath
.
setSummary
(
modelPath
);
etModelPath
.
setText
(
modelPath
);
etLabelPath
.
setSummary
(
labelPath
);
etLabelPath
.
setText
(
labelPath
);
etImagePath
.
setSummary
(
imagePath
);
etImagePath
.
setValue
(
imagePath
);
lpCPUThreadNum
.
setValue
(
cpuThreadNum
);
lpCPUThreadNum
.
setSummary
(
cpuThreadNum
);
lpCPUPowerMode
.
setValue
(
cpuPowerMode
);
lpCPUPowerMode
.
setSummary
(
cpuPowerMode
);
lpInputColorFormat
.
setValue
(
inputColorFormat
);
lpInputColorFormat
.
setSummary
(
inputColorFormat
);
etInputShape
.
setSummary
(
inputShape
);
etInputShape
.
setText
(
inputShape
);
etInputMean
.
setSummary
(
inputMean
);
etInputMean
.
setText
(
inputMean
);
etInputStd
.
setSummary
(
inputStd
);
etInputStd
.
setText
(
inputStd
);
etScoreThreshold
.
setText
(
scoreThreshold
);
etScoreThreshold
.
setSummary
(
scoreThreshold
);
}
@Override
protected
void
onResume
()
{
super
.
onResume
();
getPreferenceScreen
().
getSharedPreferences
().
registerOnSharedPreferenceChangeListener
(
this
);
reloadPreferenceAndUpdateUI
();
}
@Override
protected
void
onPause
()
{
super
.
onPause
();
getPreferenceScreen
().
getSharedPreferences
().
unregisterOnSharedPreferenceChangeListener
(
this
);
}
@Override
public
void
onSharedPreferenceChanged
(
SharedPreferences
sharedPreferences
,
String
key
)
{
if
(
key
.
equals
(
getString
(
R
.
string
.
CHOOSE_PRE_INSTALLED_MODEL_KEY
)))
{
SharedPreferences
.
Editor
editor
=
sharedPreferences
.
edit
();
editor
.
putBoolean
(
getString
(
R
.
string
.
ENABLE_CUSTOM_SETTINGS_KEY
),
false
);
editor
.
commit
();
}
reloadPreferenceAndUpdateUI
();
}
}
deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/Utils.java
0 → 100644
View file @
19eb7eb8
package
com.baidu.paddle.lite.demo.ocr
;
import
android.content.Context
;
import
android.graphics.Bitmap
;
import
android.graphics.Matrix
;
import
android.media.ExifInterface
;
import
android.os.Environment
;
import
java.io.*
;
public
class
Utils
{
private
static
final
String
TAG
=
Utils
.
class
.
getSimpleName
();
public
static
void
copyFileFromAssets
(
Context
appCtx
,
String
srcPath
,
String
dstPath
)
{
if
(
srcPath
.
isEmpty
()
||
dstPath
.
isEmpty
())
{
return
;
}
InputStream
is
=
null
;
OutputStream
os
=
null
;
try
{
is
=
new
BufferedInputStream
(
appCtx
.
getAssets
().
open
(
srcPath
));
os
=
new
BufferedOutputStream
(
new
FileOutputStream
(
new
File
(
dstPath
)));
byte
[]
buffer
=
new
byte
[
1024
];
int
length
=
0
;
while
((
length
=
is
.
read
(
buffer
))
!=
-
1
)
{
os
.
write
(
buffer
,
0
,
length
);
}
}
catch
(
FileNotFoundException
e
)
{
e
.
printStackTrace
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
finally
{
try
{
os
.
close
();
is
.
close
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
}
public
static
void
copyDirectoryFromAssets
(
Context
appCtx
,
String
srcDir
,
String
dstDir
)
{
if
(
srcDir
.
isEmpty
()
||
dstDir
.
isEmpty
())
{
return
;
}
try
{
if
(!
new
File
(
dstDir
).
exists
())
{
new
File
(
dstDir
).
mkdirs
();
}
for
(
String
fileName
:
appCtx
.
getAssets
().
list
(
srcDir
))
{
String
srcSubPath
=
srcDir
+
File
.
separator
+
fileName
;
String
dstSubPath
=
dstDir
+
File
.
separator
+
fileName
;
if
(
new
File
(
srcSubPath
).
isDirectory
())
{
copyDirectoryFromAssets
(
appCtx
,
srcSubPath
,
dstSubPath
);
}
else
{
copyFileFromAssets
(
appCtx
,
srcSubPath
,
dstSubPath
);
}
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
public
static
float
[]
parseFloatsFromString
(
String
string
,
String
delimiter
)
{
String
[]
pieces
=
string
.
trim
().
toLowerCase
().
split
(
delimiter
);
float
[]
floats
=
new
float
[
pieces
.
length
];
for
(
int
i
=
0
;
i
<
pieces
.
length
;
i
++)
{
floats
[
i
]
=
Float
.
parseFloat
(
pieces
[
i
].
trim
());
}
return
floats
;
}
public
static
long
[]
parseLongsFromString
(
String
string
,
String
delimiter
)
{
String
[]
pieces
=
string
.
trim
().
toLowerCase
().
split
(
delimiter
);
long
[]
longs
=
new
long
[
pieces
.
length
];
for
(
int
i
=
0
;
i
<
pieces
.
length
;
i
++)
{
longs
[
i
]
=
Long
.
parseLong
(
pieces
[
i
].
trim
());
}
return
longs
;
}
public
static
String
getSDCardDirectory
()
{
return
Environment
.
getExternalStorageDirectory
().
getAbsolutePath
();
}
public
static
boolean
isSupportedNPU
()
{
return
false
;
// String hardware = android.os.Build.HARDWARE;
// return hardware.equalsIgnoreCase("kirin810") || hardware.equalsIgnoreCase("kirin990");
}
public
static
Bitmap
resizeWithStep
(
Bitmap
bitmap
,
int
maxLength
,
int
step
)
{
int
width
=
bitmap
.
getWidth
();
int
height
=
bitmap
.
getHeight
();
int
maxWH
=
Math
.
max
(
width
,
height
);
float
ratio
=
1
;
int
newWidth
=
width
;
int
newHeight
=
height
;
if
(
maxWH
>
maxLength
)
{
ratio
=
maxLength
*
1.0f
/
maxWH
;
newWidth
=
(
int
)
Math
.
floor
(
ratio
*
width
);
newHeight
=
(
int
)
Math
.
floor
(
ratio
*
height
);
}
newWidth
=
newWidth
-
newWidth
%
step
;
if
(
newWidth
==
0
)
{
newWidth
=
step
;
}
newHeight
=
newHeight
-
newHeight
%
step
;
if
(
newHeight
==
0
)
{
newHeight
=
step
;
}
return
Bitmap
.
createScaledBitmap
(
bitmap
,
newWidth
,
newHeight
,
true
);
}
public
static
Bitmap
rotateBitmap
(
Bitmap
bitmap
,
int
orientation
)
{
Matrix
matrix
=
new
Matrix
();
switch
(
orientation
)
{
case
ExifInterface
.
ORIENTATION_NORMAL
:
return
bitmap
;
case
ExifInterface
.
ORIENTATION_FLIP_HORIZONTAL
:
matrix
.
setScale
(-
1
,
1
);
break
;
case
ExifInterface
.
ORIENTATION_ROTATE_180
:
matrix
.
setRotate
(
180
);
break
;
case
ExifInterface
.
ORIENTATION_FLIP_VERTICAL
:
matrix
.
setRotate
(
180
);
matrix
.
postScale
(-
1
,
1
);
break
;
case
ExifInterface
.
ORIENTATION_TRANSPOSE
:
matrix
.
setRotate
(
90
);
matrix
.
postScale
(-
1
,
1
);
break
;
case
ExifInterface
.
ORIENTATION_ROTATE_90
:
matrix
.
setRotate
(
90
);
break
;
case
ExifInterface
.
ORIENTATION_TRANSVERSE
:
matrix
.
setRotate
(-
90
);
matrix
.
postScale
(-
1
,
1
);
break
;
case
ExifInterface
.
ORIENTATION_ROTATE_270
:
matrix
.
setRotate
(-
90
);
break
;
default
:
return
bitmap
;
}
try
{
Bitmap
bmRotated
=
Bitmap
.
createBitmap
(
bitmap
,
0
,
0
,
bitmap
.
getWidth
(),
bitmap
.
getHeight
(),
matrix
,
true
);
bitmap
.
recycle
();
return
bmRotated
;
}
catch
(
OutOfMemoryError
e
)
{
e
.
printStackTrace
();
return
null
;
}
}
}
deploy/android_demo/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
0 → 100644
View file @
19eb7eb8
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:aapt=
"http://schemas.android.com/aapt"
android:width=
"108dp"
android:height=
"108dp"
android:viewportWidth=
"108"
android:viewportHeight=
"108"
>
<path
android:fillType=
"evenOdd"
android:pathData=
"M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeWidth=
"1"
android:strokeColor=
"#00000000"
>
<aapt:attr
name=
"android:fillColor"
>
<gradient
android:endX=
"78.5885"
android:endY=
"90.9159"
android:startX=
"48.7653"
android:startY=
"61.0927"
android:type=
"linear"
>
<item
android:color=
"#44000000"
android:offset=
"0.0"
/>
<item
android:color=
"#00000000"
android:offset=
"1.0"
/>
</gradient>
</aapt:attr>
</path>
<path
android:fillColor=
"#FFFFFF"
android:fillType=
"nonZero"
android:pathData=
"M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeWidth=
"1"
android:strokeColor=
"#00000000"
/>
</vector>
deploy/android_demo/app/src/main/res/drawable/ic_launcher_background.xml
0 → 100644
View file @
19eb7eb8
<?xml version="1.0" encoding="utf-8"?>
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"108dp"
android:height=
"108dp"
android:viewportWidth=
"108"
android:viewportHeight=
"108"
>
<path
android:fillColor=
"#008577"
android:pathData=
"M0,0h108v108h-108z"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M9,0L9,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M19,0L19,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M29,0L29,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M39,0L39,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M49,0L49,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M59,0L59,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M69,0L69,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M79,0L79,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M89,0L89,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M99,0L99,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,9L108,9"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,19L108,19"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,29L108,29"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,39L108,39"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,49L108,49"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,59L108,59"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,69L108,69"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,79L108,79"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,89L108,89"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,99L108,99"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M19,29L89,29"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M19,39L89,39"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M19,49L89,49"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M19,59L89,59"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M19,69L89,69"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M19,79L89,79"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M29,19L29,89"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M39,19L39,89"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M49,19L49,89"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M59,19L59,89"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M69,19L69,89"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M79,19L79,89"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
</vector>
deploy/android_demo/app/src/main/res/layout/activity_main.xml
0 → 100644
View file @
19eb7eb8
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
tools:context=
".MainActivity"
>
<RelativeLayout
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
<LinearLayout
android:id=
"@+id/v_input_info"
android:layout_width=
"fill_parent"
android:layout_height=
"wrap_content"
android:layout_alignParentTop=
"true"
android:orientation=
"vertical"
>
<LinearLayout
android:id=
"@+id/btn_layout"
android:layout_width=
"fill_parent"
android:layout_height=
"wrap_content"
android:orientation=
"horizontal"
>
<Button
android:id=
"@+id/btn_load_model"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_weight=
"1"
android:onClick=
"btn_load_model_click"
android:text=
"加载模型"
/>
<Button
android:id=
"@+id/btn_run_model"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_weight=
"1"
android:onClick=
"btn_run_model_click"
android:text=
"运行模型"
/>
<Button
android:id=
"@+id/btn_take_photo"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_weight=
"1"
android:onClick=
"btn_take_photo_click"
android:text=
"拍照识别"
/>
<Button
android:id=
"@+id/btn_choice_img"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_weight=
"1"
android:onClick=
"btn_choice_img_click"
android:text=
"选取图片"
/>
</LinearLayout>
<TextView
android:id=
"@+id/tv_input_setting"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:scrollbars=
"vertical"
android:layout_marginLeft=
"12dp"
android:layout_marginRight=
"12dp"
android:layout_marginTop=
"10dp"
android:layout_marginBottom=
"5dp"
android:lineSpacingExtra=
"4dp"
android:singleLine=
"false"
android:maxLines=
"6"
android:text=
""
/>
<TextView
android:id=
"@+id/tv_model_img_status"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:scrollbars=
"vertical"
android:layout_marginLeft=
"12dp"
android:layout_marginRight=
"12dp"
android:layout_marginTop=
"-5dp"
android:layout_marginBottom=
"5dp"
android:lineSpacingExtra=
"4dp"
android:singleLine=
"false"
android:maxLines=
"6"
android:text=
"STATUS: ok"
/>
</LinearLayout>
<RelativeLayout
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:layout_above=
"@+id/v_output_info"
android:layout_below=
"@+id/v_input_info"
>
<ImageView
android:id=
"@+id/iv_input_image"
android:layout_width=
"400dp"
android:layout_height=
"400dp"
android:layout_centerHorizontal=
"true"
android:layout_centerVertical=
"true"
android:layout_marginLeft=
"12dp"
android:layout_marginRight=
"12dp"
android:layout_marginTop=
"5dp"
android:layout_marginBottom=
"5dp"
android:adjustViewBounds=
"true"
android:scaleType=
"fitCenter"
/>
</RelativeLayout>
<RelativeLayout
android:id=
"@+id/v_output_info"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_alignParentBottom=
"true"
android:layout_centerHorizontal=
"true"
>
<TextView
android:id=
"@+id/tv_output_result"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_alignParentTop=
"true"
android:layout_centerHorizontal=
"true"
android:layout_centerVertical=
"true"
android:scrollbars=
"vertical"
android:layout_marginLeft=
"12dp"
android:layout_marginRight=
"12dp"
android:layout_marginTop=
"5dp"
android:layout_marginBottom=
"5dp"
android:textAlignment=
"center"
android:lineSpacingExtra=
"5dp"
android:singleLine=
"false"
android:maxLines=
"5"
android:text=
""
/>
<TextView
android:id=
"@+id/tv_inference_time"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_below=
"@+id/tv_output_result"
android:layout_centerHorizontal=
"true"
android:layout_centerVertical=
"true"
android:textAlignment=
"center"
android:layout_marginLeft=
"12dp"
android:layout_marginRight=
"12dp"
android:layout_marginTop=
"5dp"
android:layout_marginBottom=
"10dp"
android:text=
""
/>
</RelativeLayout>
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
deploy/android_demo/app/src/main/res/layout/activity_mini.xml
0 → 100644
View file @
19eb7eb8
<?xml version="1.0" encoding="utf-8"?>
<!-- for MiniActivity Use Only -->
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
app:layout_constraintLeft_toLeftOf=
"parent"
app:layout_constraintLeft_toRightOf=
"parent"
tools:context=
".MainActivity"
>
<TextView
android:id=
"@+id/sample_text"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:text=
"Hello World!"
app:layout_constraintLeft_toLeftOf=
"parent"
app:layout_constraintRight_toRightOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@id/imageView"
android:scrollbars=
"vertical"
/>
<ImageView
android:id=
"@+id/imageView"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:paddingTop=
"20dp"
android:paddingBottom=
"20dp"
app:layout_constraintBottom_toTopOf=
"@id/imageView"
app:layout_constraintLeft_toLeftOf=
"parent"
app:layout_constraintRight_toRightOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
tools:srcCompat=
"@tools:sample/avatars"
/>
<Button
android:id=
"@+id/button"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginBottom=
"4dp"
android:text=
"Button"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintLeft_toLeftOf=
"parent"
app:layout_constraintRight_toRightOf=
"parent"
tools:layout_editor_absoluteX=
"161dp"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
deploy/android_demo/app/src/main/res/menu/menu_action_options.xml
0 → 100644
View file @
19eb7eb8
<menu
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
>
<group>
<item
android:id=
"@+id/settings"
android:title=
"Settings..."
app:showAsAction=
"withText"
/>
</group>
</menu>
deploy/android_demo/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
0 → 100644
View file @
19eb7eb8
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<background
android:drawable=
"@drawable/ic_launcher_background"
/>
<foreground
android:drawable=
"@drawable/ic_launcher_foreground"
/>
</adaptive-icon>
\ No newline at end of file
deploy/android_demo/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
0 → 100644
View file @
19eb7eb8
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<background
android:drawable=
"@drawable/ic_launcher_background"
/>
<foreground
android:drawable=
"@drawable/ic_launcher_foreground"
/>
</adaptive-icon>
\ No newline at end of file
deploy/android_demo/app/src/main/res/mipmap-hdpi/ic_launcher.png
0 → 100644
View file @
19eb7eb8
2.89 KB
deploy/android_demo/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
0 → 100644
View file @
19eb7eb8
4.79 KB
Prev
1
2
3
4
5
6
7
8
9
…
19
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment