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
191c9dee
Unverified
Commit
191c9dee
authored
Mar 18, 2022
by
Evezerest
Committed by
GitHub
Mar 18, 2022
Browse files
Merge branch 'dygraph' into dygraph
parents
3c6d5512
8def6786
Changes
161
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
509 additions
and
612 deletions
+509
-612
deploy/android_demo/app/src/main/assets/images/rec_1.jpg
deploy/android_demo/app/src/main/assets/images/rec_1.jpg
+0
-0
deploy/android_demo/app/src/main/assets/images/rec_1_180.jpg
deploy/android_demo/app/src/main/assets/images/rec_1_180.jpg
+0
-0
deploy/android_demo/app/src/main/cpp/native.cpp
deploy/android_demo/app/src/main/cpp/native.cpp
+17
-12
deploy/android_demo/app/src/main/cpp/ocr_ppredictor.cpp
deploy/android_demo/app/src/main/cpp/ocr_ppredictor.cpp
+157
-68
deploy/android_demo/app/src/main/cpp/ocr_ppredictor.h
deploy/android_demo/app/src/main/cpp/ocr_ppredictor.h
+17
-9
deploy/android_demo/app/src/main/cpp/ppredictor.cpp
deploy/android_demo/app/src/main/cpp/ppredictor.cpp
+36
-6
deploy/android_demo/app/src/main/cpp/ppredictor.h
deploy/android_demo/app/src/main/cpp/ppredictor.h
+2
-1
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
+91
-80
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
+0
-157
deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/OCRPredictorNative.java
...va/com/baidu/paddle/lite/demo/ocr/OCRPredictorNative.java
+19
-16
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
+27
-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
+37
-116
deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/SettingsActivity.java
...java/com/baidu/paddle/lite/demo/ocr/SettingsActivity.java
+11
-40
deploy/android_demo/app/src/main/res/layout/activity_main.xml
...oy/android_demo/app/src/main/res/layout/activity_main.xml
+40
-8
deploy/android_demo/app/src/main/res/layout/activity_mini.xml
...oy/android_demo/app/src/main/res/layout/activity_mini.xml
+0
-46
deploy/android_demo/app/src/main/res/values/arrays.xml
deploy/android_demo/app/src/main/res/values/arrays.xml
+24
-8
deploy/android_demo/app/src/main/res/values/strings.xml
deploy/android_demo/app/src/main/res/values/strings.xml
+5
-11
deploy/android_demo/app/src/main/res/xml/settings.xml
deploy/android_demo/app/src/main/res/xml/settings.xml
+3
-19
deploy/cpp_infer/include/ocr_det.h
deploy/cpp_infer/include/ocr_det.h
+7
-3
deploy/cpp_infer/readme.md
deploy/cpp_infer/readme.md
+16
-12
No files found.
deploy/android_demo/app/src/main/assets/images/rec_1.jpg
0 → 100644
View file @
191c9dee
7.75 KB
deploy/android_demo/app/src/main/assets/images/rec_1_180.jpg
0 → 100644
View file @
191c9dee
8.06 KB
deploy/android_demo/app/src/main/cpp/native.cpp
View file @
191c9dee
...
...
@@ -13,7 +13,7 @@ static paddle::lite_api::PowerMode str_to_cpu_mode(const std::string &cpu_mode);
extern
"C"
JNIEXPORT
jlong
JNICALL
Java_com_baidu_paddle_lite_demo_ocr_OCRPredictorNative_init
(
JNIEnv
*
env
,
jobject
thiz
,
jstring
j_det_model_path
,
jstring
j_rec_model_path
,
jstring
j_cls_model_path
,
jint
j_thread_num
,
jstring
j_rec_model_path
,
jstring
j_cls_model_path
,
jint
j_use_opencl
,
jint
j_thread_num
,
jstring
j_cpu_mode
)
{
std
::
string
det_model_path
=
jstring_to_cpp_string
(
env
,
j_det_model_path
);
std
::
string
rec_model_path
=
jstring_to_cpp_string
(
env
,
j_rec_model_path
);
...
...
@@ -21,6 +21,7 @@ Java_com_baidu_paddle_lite_demo_ocr_OCRPredictorNative_init(
int
thread_num
=
j_thread_num
;
std
::
string
cpu_mode
=
jstring_to_cpp_string
(
env
,
j_cpu_mode
);
ppredictor
::
OCR_Config
conf
;
conf
.
use_opencl
=
j_use_opencl
;
conf
.
thread_num
=
thread_num
;
conf
.
mode
=
str_to_cpu_mode
(
cpu_mode
);
ppredictor
::
OCR_PPredictor
*
orc_predictor
=
...
...
@@ -57,32 +58,31 @@ str_to_cpu_mode(const std::string &cpu_mode) {
extern
"C"
JNIEXPORT
jfloatArray
JNICALL
Java_com_baidu_paddle_lite_demo_ocr_OCRPredictorNative_forward
(
JNIEnv
*
env
,
jobject
thiz
,
jlong
java_pointer
,
jfloatArray
buf
,
jfloatArray
ddims
,
jobject
original_image
)
{
JNIEnv
*
env
,
jobject
thiz
,
jlong
java_pointer
,
jobject
original_image
,
jint
j_max_size_len
,
jint
j_run_det
,
jint
j_run_cls
,
jint
j_run_rec
)
{
LOGI
(
"begin to run native forward"
);
if
(
java_pointer
==
0
)
{
LOGE
(
"JAVA pointer is NULL"
);
return
cpp_array_to_jfloatarray
(
env
,
nullptr
,
0
);
}
cv
::
Mat
origin
=
bitmap_to_cv_mat
(
env
,
original_image
);
if
(
origin
.
size
==
0
)
{
LOGE
(
"origin bitmap cannot convert to CV Mat"
);
return
cpp_array_to_jfloatarray
(
env
,
nullptr
,
0
);
}
int
max_size_len
=
j_max_size_len
;
int
run_det
=
j_run_det
;
int
run_cls
=
j_run_cls
;
int
run_rec
=
j_run_rec
;
ppredictor
::
OCR_PPredictor
*
ppredictor
=
(
ppredictor
::
OCR_PPredictor
*
)
java_pointer
;
std
::
vector
<
float
>
dims_float_arr
=
jfloatarray_to_float_vector
(
env
,
ddims
);
std
::
vector
<
int64_t
>
dims_arr
;
dims_arr
.
resize
(
dims_float_arr
.
size
());
std
::
copy
(
dims_float_arr
.
cbegin
(),
dims_float_arr
.
cend
(),
dims_arr
.
begin
());
// 这里值有点大,就不调用jfloatarray_to_float_vector了
int64_t
buf_len
=
(
int64_t
)
env
->
GetArrayLength
(
buf
);
jfloat
*
buf_data
=
env
->
GetFloatArrayElements
(
buf
,
JNI_FALSE
);
float
*
data
=
(
jfloat
*
)
buf_data
;
std
::
vector
<
ppredictor
::
OCRPredictResult
>
results
=
ppredictor
->
infer_ocr
(
dims_arr
,
data
,
buf_len
,
NET_OCR
,
origin
);
ppredictor
->
infer_ocr
(
origin
,
max_size_len
,
run_det
,
run_cls
,
run_rec
);
LOGI
(
"infer_ocr finished with boxes %ld"
,
results
.
size
());
// 这里将std::vector<ppredictor::OCRPredictResult> 序列化成
// float数组,传输到java层再反序列化
std
::
vector
<
float
>
float_arr
;
...
...
@@ -90,13 +90,18 @@ Java_com_baidu_paddle_lite_demo_ocr_OCRPredictorNative_forward(
float_arr
.
push_back
(
r
.
points
.
size
());
float_arr
.
push_back
(
r
.
word_index
.
size
());
float_arr
.
push_back
(
r
.
score
);
// add det point
for
(
const
std
::
vector
<
int
>
&
point
:
r
.
points
)
{
float_arr
.
push_back
(
point
.
at
(
0
));
float_arr
.
push_back
(
point
.
at
(
1
));
}
// add rec word idx
for
(
int
index
:
r
.
word_index
)
{
float_arr
.
push_back
(
index
);
}
// add cls result
float_arr
.
push_back
(
r
.
cls_label
);
float_arr
.
push_back
(
r
.
cls_score
);
}
return
cpp_array_to_jfloatarray
(
env
,
float_arr
.
data
(),
float_arr
.
size
());
}
...
...
deploy/android_demo/app/src/main/cpp/ocr_ppredictor.cpp
View file @
191c9dee
...
...
@@ -17,15 +17,15 @@ int OCR_PPredictor::init(const std::string &det_model_content,
const
std
::
string
&
rec_model_content
,
const
std
::
string
&
cls_model_content
)
{
_det_predictor
=
std
::
unique_ptr
<
PPredictor
>
(
new
PPredictor
{
_config
.
thread_num
,
NET_OCR
,
_config
.
mode
});
new
PPredictor
{
_config
.
use_opencl
,
_config
.
thread_num
,
NET_OCR
,
_config
.
mode
});
_det_predictor
->
init_nb
(
det_model_content
);
_rec_predictor
=
std
::
unique_ptr
<
PPredictor
>
(
new
PPredictor
{
_config
.
thread_num
,
NET_OCR_INTERNAL
,
_config
.
mode
});
new
PPredictor
{
_config
.
use_opencl
,
_config
.
thread_num
,
NET_OCR_INTERNAL
,
_config
.
mode
});
_rec_predictor
->
init_nb
(
rec_model_content
);
_cls_predictor
=
std
::
unique_ptr
<
PPredictor
>
(
new
PPredictor
{
_config
.
thread_num
,
NET_OCR_INTERNAL
,
_config
.
mode
});
new
PPredictor
{
_config
.
use_opencl
,
_config
.
thread_num
,
NET_OCR_INTERNAL
,
_config
.
mode
});
_cls_predictor
->
init_nb
(
cls_model_content
);
return
RETURN_OK
;
}
...
...
@@ -34,15 +34,16 @@ int OCR_PPredictor::init_from_file(const std::string &det_model_path,
const
std
::
string
&
rec_model_path
,
const
std
::
string
&
cls_model_path
)
{
_det_predictor
=
std
::
unique_ptr
<
PPredictor
>
(
new
PPredictor
{
_config
.
thread_num
,
NET_OCR
,
_config
.
mode
});
new
PPredictor
{
_config
.
use_opencl
,
_config
.
thread_num
,
NET_OCR
,
_config
.
mode
});
_det_predictor
->
init_from_file
(
det_model_path
);
_rec_predictor
=
std
::
unique_ptr
<
PPredictor
>
(
new
PPredictor
{
_config
.
thread_num
,
NET_OCR_INTERNAL
,
_config
.
mode
});
new
PPredictor
{
_config
.
use_opencl
,
_config
.
thread_num
,
NET_OCR_INTERNAL
,
_config
.
mode
});
_rec_predictor
->
init_from_file
(
rec_model_path
);
_cls_predictor
=
std
::
unique_ptr
<
PPredictor
>
(
new
PPredictor
{
_config
.
thread_num
,
NET_OCR_INTERNAL
,
_config
.
mode
});
new
PPredictor
{
_config
.
use_opencl
,
_config
.
thread_num
,
NET_OCR_INTERNAL
,
_config
.
mode
});
_cls_predictor
->
init_from_file
(
cls_model_path
);
return
RETURN_OK
;
}
...
...
@@ -77,33 +78,126 @@ visual_img(const std::vector<std::vector<std::vector<int>>> &filter_boxes,
}
std
::
vector
<
OCRPredictResult
>
OCR_PPredictor
::
infer_ocr
(
const
std
::
vector
<
int64_t
>
&
dims
,
const
float
*
input_data
,
int
input_len
,
int
net_flag
,
cv
::
Mat
&
origin
)
{
OCR_PPredictor
::
infer_ocr
(
cv
::
Mat
&
origin
,
int
max_size_len
,
int
run_det
,
int
run_cls
,
int
run_rec
)
{
LOGI
(
"ocr cpp start *****************"
);
LOGI
(
"ocr cpp det: %d, cls: %d, rec: %d"
,
run_det
,
run_cls
,
run_rec
);
std
::
vector
<
OCRPredictResult
>
ocr_results
;
if
(
run_det
){
infer_det
(
origin
,
max_size_len
,
ocr_results
);
}
if
(
run_rec
){
if
(
ocr_results
.
size
()
==
0
){
OCRPredictResult
res
;
ocr_results
.
emplace_back
(
std
::
move
(
res
));
}
for
(
int
i
=
0
;
i
<
ocr_results
.
size
();
i
++
)
{
infer_rec
(
origin
,
run_cls
,
ocr_results
[
i
]);
}
}
else
if
(
run_cls
){
ClsPredictResult
cls_res
=
infer_cls
(
origin
);
OCRPredictResult
res
;
res
.
cls_score
=
cls_res
.
cls_score
;
res
.
cls_label
=
cls_res
.
cls_label
;
ocr_results
.
push_back
(
res
);
}
LOGI
(
"ocr cpp end *****************"
);
return
ocr_results
;
}
cv
::
Mat
DetResizeImg
(
const
cv
::
Mat
img
,
int
max_size_len
,
std
::
vector
<
float
>
&
ratio_hw
)
{
int
w
=
img
.
cols
;
int
h
=
img
.
rows
;
float
ratio
=
1.
f
;
int
max_wh
=
w
>=
h
?
w
:
h
;
if
(
max_wh
>
max_size_len
)
{
if
(
h
>
w
)
{
ratio
=
static_cast
<
float
>
(
max_size_len
)
/
static_cast
<
float
>
(
h
);
}
else
{
ratio
=
static_cast
<
float
>
(
max_size_len
)
/
static_cast
<
float
>
(
w
);
}
}
int
resize_h
=
static_cast
<
int
>
(
float
(
h
)
*
ratio
);
int
resize_w
=
static_cast
<
int
>
(
float
(
w
)
*
ratio
);
if
(
resize_h
%
32
==
0
)
resize_h
=
resize_h
;
else
if
(
resize_h
/
32
<
1
+
1e-5
)
resize_h
=
32
;
else
resize_h
=
(
resize_h
/
32
-
1
)
*
32
;
if
(
resize_w
%
32
==
0
)
resize_w
=
resize_w
;
else
if
(
resize_w
/
32
<
1
+
1e-5
)
resize_w
=
32
;
else
resize_w
=
(
resize_w
/
32
-
1
)
*
32
;
cv
::
Mat
resize_img
;
cv
::
resize
(
img
,
resize_img
,
cv
::
Size
(
resize_w
,
resize_h
));
ratio_hw
.
push_back
(
static_cast
<
float
>
(
resize_h
)
/
static_cast
<
float
>
(
h
));
ratio_hw
.
push_back
(
static_cast
<
float
>
(
resize_w
)
/
static_cast
<
float
>
(
w
));
return
resize_img
;
}
void
OCR_PPredictor
::
infer_det
(
cv
::
Mat
&
origin
,
int
max_size_len
,
std
::
vector
<
OCRPredictResult
>
&
ocr_results
)
{
std
::
vector
<
float
>
mean
=
{
0.485
f
,
0.456
f
,
0.406
f
};
std
::
vector
<
float
>
scale
=
{
1
/
0.229
f
,
1
/
0.224
f
,
1
/
0.225
f
};
PredictorInput
input
=
_det_predictor
->
get_first_input
();
input
.
set_dims
(
dims
);
input
.
set_data
(
input_data
,
input_len
);
std
::
vector
<
float
>
ratio_hw
;
cv
::
Mat
input_image
=
DetResizeImg
(
origin
,
max_size_len
,
ratio_hw
);
input_image
.
convertTo
(
input_image
,
CV_32FC3
,
1
/
255.0
f
);
const
float
*
dimg
=
reinterpret_cast
<
const
float
*>
(
input_image
.
data
);
int
input_size
=
input_image
.
rows
*
input_image
.
cols
;
input
.
set_dims
({
1
,
3
,
input_image
.
rows
,
input_image
.
cols
});
neon_mean_scale
(
dimg
,
input
.
get_mutable_float_data
(),
input_size
,
mean
,
scale
);
LOGI
(
"ocr cpp det shape %d,%d"
,
input_image
.
rows
,
input_image
.
cols
);
std
::
vector
<
PredictorOutput
>
results
=
_det_predictor
->
infer
();
PredictorOutput
&
res
=
results
.
at
(
0
);
std
::
vector
<
std
::
vector
<
std
::
vector
<
int
>>>
filtered_box
=
calc_filtered_boxes
(
res
.
get_float_data
(),
res
.
get_size
(),
(
int
)
dims
[
2
],
(
int
)
dims
[
3
],
origin
);
LOGI
(
"Filter_box size %ld"
,
filtered_box
.
size
());
return
infer_rec
(
filtered_box
,
origin
);
res
.
get_float_data
(),
res
.
get_size
(),
input_image
.
rows
,
input_image
.
cols
,
origin
);
LOGI
(
"ocr cpp det Filter_box size %ld"
,
filtered_box
.
size
());
for
(
int
i
=
0
;
i
<
filtered_box
.
size
();
i
++
){
LOGI
(
"ocr cpp box %d,%d,%d,%d,%d,%d,%d,%d"
,
filtered_box
[
i
][
0
][
0
],
filtered_box
[
i
][
0
][
1
],
filtered_box
[
i
][
1
][
0
],
filtered_box
[
i
][
1
][
1
],
filtered_box
[
i
][
2
][
0
],
filtered_box
[
i
][
2
][
1
],
filtered_box
[
i
][
3
][
0
],
filtered_box
[
i
][
3
][
1
]);
OCRPredictResult
res
;
res
.
points
=
filtered_box
[
i
];
ocr_results
.
push_back
(
res
);
}
}
std
::
vector
<
OCRPredictResult
>
OCR_PPredictor
::
infer_rec
(
const
std
::
vector
<
std
::
vector
<
std
::
vector
<
int
>>>
&
boxes
,
const
cv
::
Mat
&
origin_img
)
{
void
OCR_PPredictor
::
infer_rec
(
const
cv
::
Mat
&
origin_img
,
int
run_cls
,
OCRPredictResult
&
ocr_result
)
{
std
::
vector
<
float
>
mean
=
{
0.5
f
,
0.5
f
,
0.5
f
};
std
::
vector
<
float
>
scale
=
{
1
/
0.5
f
,
1
/
0.5
f
,
1
/
0.5
f
};
std
::
vector
<
int64_t
>
dims
=
{
1
,
3
,
0
,
0
};
std
::
vector
<
OCRPredictResult
>
ocr_results
;
PredictorInput
input
=
_rec_predictor
->
get_first_input
();
for
(
auto
bp
=
boxes
.
crbegin
();
bp
!=
boxes
.
crend
();
++
bp
)
{
const
std
::
vector
<
std
::
vector
<
int
>>
&
box
=
*
bp
;
cv
::
Mat
crop_img
=
get_rotate_crop_image
(
origin_img
,
box
);
crop_img
=
infer_cls
(
crop_img
);
const
std
::
vector
<
std
::
vector
<
int
>>
&
box
=
ocr_result
.
points
;
cv
::
Mat
crop_img
;
if
(
box
.
size
()
>
0
){
crop_img
=
get_rotate_crop_image
(
origin_img
,
box
);
}
else
{
crop_img
=
origin_img
;
}
if
(
run_cls
){
ClsPredictResult
cls_res
=
infer_cls
(
crop_img
);
crop_img
=
cls_res
.
img
;
ocr_result
.
cls_score
=
cls_res
.
cls_score
;
ocr_result
.
cls_label
=
cls_res
.
cls_label
;
}
float
wh_ratio
=
float
(
crop_img
.
cols
)
/
float
(
crop_img
.
rows
);
cv
::
Mat
input_image
=
crnn_resize_img
(
crop_img
,
wh_ratio
);
...
...
@@ -122,8 +216,6 @@ std::vector<OCRPredictResult> OCR_PPredictor::infer_rec(
const
float
*
predict_batch
=
results
.
at
(
0
).
get_float_data
();
const
std
::
vector
<
int64_t
>
predict_shape
=
results
.
at
(
0
).
get_shape
();
OCRPredictResult
res
;
// ctc decode
int
argmax_idx
;
int
last_index
=
0
;
...
...
@@ -140,27 +232,19 @@ std::vector<OCRPredictResult> OCR_PPredictor::infer_rec(
if
(
argmax_idx
>
0
&&
(
!
(
n
>
0
&&
argmax_idx
==
last_index
)))
{
score
+=
max_value
;
count
+=
1
;
res
.
word_index
.
push_back
(
argmax_idx
);
ocr_result
.
word_index
.
push_back
(
argmax_idx
);
}
last_index
=
argmax_idx
;
}
score
/=
count
;
if
(
res
.
word_index
.
empty
())
{
continue
;
}
res
.
score
=
score
;
res
.
points
=
box
;
ocr_results
.
emplace_back
(
std
::
move
(
res
));
}
LOGI
(
"ocr_results finished %lu"
,
ocr_results
.
size
());
return
ocr_results
;
ocr_result
.
score
=
score
;
LOGI
(
"ocr cpp rec word size %ld"
,
count
);
}
cv
::
Ma
t
OCR_PPredictor
::
infer_cls
(
const
cv
::
Mat
&
img
,
float
thresh
)
{
ClsPredictResul
t
OCR_PPredictor
::
infer_cls
(
const
cv
::
Mat
&
img
,
float
thresh
)
{
std
::
vector
<
float
>
mean
=
{
0.5
f
,
0.5
f
,
0.5
f
};
std
::
vector
<
float
>
scale
=
{
1
/
0.5
f
,
1
/
0.5
f
,
1
/
0.5
f
};
std
::
vector
<
int64_t
>
dims
=
{
1
,
3
,
0
,
0
};
std
::
vector
<
OCRPredictResult
>
ocr_results
;
PredictorInput
input
=
_cls_predictor
->
get_first_input
();
...
...
@@ -182,7 +266,7 @@ cv::Mat OCR_PPredictor::infer_cls(const cv::Mat &img, float thresh) {
float
score
=
0
;
int
label
=
0
;
for
(
int64_t
i
=
0
;
i
<
results
.
at
(
0
).
get_size
();
i
++
)
{
LOGI
(
"output scores [%f]"
,
scores
[
i
]);
LOGI
(
"
ocr cpp cls
output scores [%f]"
,
scores
[
i
]);
if
(
scores
[
i
]
>
score
)
{
score
=
scores
[
i
];
label
=
i
;
...
...
@@ -193,7 +277,12 @@ cv::Mat OCR_PPredictor::infer_cls(const cv::Mat &img, float thresh) {
if
(
label
%
2
==
1
&&
score
>
thresh
)
{
cv
::
rotate
(
srcimg
,
srcimg
,
1
);
}
return
srcimg
;
ClsPredictResult
res
;
res
.
cls_label
=
label
;
res
.
cls_score
=
score
;
res
.
img
=
srcimg
;
LOGI
(
"ocr cpp cls word cls %ld, %f"
,
label
,
score
);
return
res
;
}
std
::
vector
<
std
::
vector
<
std
::
vector
<
int
>>>
...
...
deploy/android_demo/app/src/main/cpp/ocr_ppredictor.h
View file @
191c9dee
...
...
@@ -15,6 +15,7 @@ namespace ppredictor {
* Config
*/
struct
OCR_Config
{
int
use_opencl
=
0
;
int
thread_num
=
4
;
// Thread num
paddle
::
lite_api
::
PowerMode
mode
=
paddle
::
lite_api
::
LITE_POWER_HIGH
;
// PaddleLite Mode
...
...
@@ -27,8 +28,15 @@ struct OCRPredictResult {
std
::
vector
<
int
>
word_index
;
std
::
vector
<
std
::
vector
<
int
>>
points
;
float
score
;
float
cls_score
;
int
cls_label
=-
1
;
};
struct
ClsPredictResult
{
float
cls_score
;
int
cls_label
=-
1
;
cv
::
Mat
img
;
};
/**
* OCR there are 2 models
* 1. First model(det),select polygones to show where are the texts
...
...
@@ -62,8 +70,7 @@ public:
* @return
*/
virtual
std
::
vector
<
OCRPredictResult
>
infer_ocr
(
const
std
::
vector
<
int64_t
>
&
dims
,
const
float
*
input_data
,
int
input_len
,
int
net_flag
,
cv
::
Mat
&
origin
);
infer_ocr
(
cv
::
Mat
&
origin
,
int
max_size_len
,
int
run_det
,
int
run_cls
,
int
run_rec
);
virtual
NET_TYPE
get_net_flag
()
const
;
...
...
@@ -80,16 +87,17 @@ private:
calc_filtered_boxes
(
const
float
*
pred
,
int
pred_size
,
int
output_height
,
int
output_width
,
const
cv
::
Mat
&
origin
);
void
infer_det
(
cv
::
Mat
&
origin
,
int
max_side_len
,
std
::
vector
<
OCRPredictResult
>&
ocr_results
);
/**
* infer for
s
ec
ond
model
* infer for
r
ec model
*
* @param boxes
* @param origin
* @return
*/
std
::
vector
<
OCRPredictResult
>
infer_rec
(
const
std
::
vector
<
std
::
vector
<
std
::
vector
<
int
>>>
&
boxes
,
const
cv
::
Mat
&
origin
);
void
infer_rec
(
const
cv
::
Mat
&
origin
,
int
run_cls
,
OCRPredictResult
&
ocr_result
);
/**
* infer for cls model
...
...
@@ -98,7 +106,7 @@ private:
* @param origin
* @return
*/
cv
::
Ma
t
infer_cls
(
const
cv
::
Mat
&
origin
,
float
thresh
=
0.9
);
ClsPredictResul
t
infer_cls
(
const
cv
::
Mat
&
origin
,
float
thresh
=
0.9
);
/**
* Postprocess or sencod model to extract text
...
...
deploy/android_demo/app/src/main/cpp/ppredictor.cpp
View file @
191c9dee
...
...
@@ -2,9 +2,9 @@
#include "common.h"
namespace
ppredictor
{
PPredictor
::
PPredictor
(
int
thread_num
,
int
net_flag
,
PPredictor
::
PPredictor
(
int
use_opencl
,
int
thread_num
,
int
net_flag
,
paddle
::
lite_api
::
PowerMode
mode
)
:
_thread_num
(
thread_num
),
_net_flag
(
net_flag
),
_mode
(
mode
)
{}
:
_use_opencl
(
use_opencl
),
_thread_num
(
thread_num
),
_net_flag
(
net_flag
),
_mode
(
mode
)
{}
int
PPredictor
::
init_nb
(
const
std
::
string
&
model_content
)
{
paddle
::
lite_api
::
MobileConfig
config
;
...
...
@@ -19,10 +19,40 @@ int PPredictor::init_from_file(const std::string &model_content) {
}
template
<
typename
ConfigT
>
int
PPredictor
::
_init
(
ConfigT
&
config
)
{
bool
is_opencl_backend_valid
=
paddle
::
lite_api
::
IsOpenCLBackendValid
(
/*check_fp16_valid = false*/
);
if
(
is_opencl_backend_valid
)
{
if
(
_use_opencl
!=
0
)
{
// Make sure you have write permission of the binary path.
// We strongly recommend each model has a unique binary name.
const
std
::
string
bin_path
=
"/data/local/tmp/"
;
const
std
::
string
bin_name
=
"lite_opencl_kernel.bin"
;
config
.
set_opencl_binary_path_name
(
bin_path
,
bin_name
);
// opencl tune option
// CL_TUNE_NONE: 0
// CL_TUNE_RAPID: 1
// CL_TUNE_NORMAL: 2
// CL_TUNE_EXHAUSTIVE: 3
const
std
::
string
tuned_path
=
"/data/local/tmp/"
;
const
std
::
string
tuned_name
=
"lite_opencl_tuned.bin"
;
config
.
set_opencl_tune
(
paddle
::
lite_api
::
CL_TUNE_NORMAL
,
tuned_path
,
tuned_name
);
// opencl precision option
// CL_PRECISION_AUTO: 0, first fp16 if valid, default
// CL_PRECISION_FP32: 1, force fp32
// CL_PRECISION_FP16: 2, force fp16
config
.
set_opencl_precision
(
paddle
::
lite_api
::
CL_PRECISION_FP32
);
LOGI
(
"ocr cpp device: running on gpu."
);
}
}
else
{
LOGI
(
"ocr cpp device: running on cpu."
);
// you can give backup cpu nb model instead
// config.set_model_from_file(cpu_nb_model_dir);
}
config
.
set_threads
(
_thread_num
);
config
.
set_power_mode
(
_mode
);
_predictor
=
paddle
::
lite_api
::
CreatePaddlePredictor
(
config
);
LOGI
(
"paddle instance created"
);
LOGI
(
"
ocr cpp
paddle instance created"
);
return
RETURN_OK
;
}
...
...
@@ -43,18 +73,18 @@ std::vector<PredictorInput> PPredictor::get_inputs(int num) {
PredictorInput
PPredictor
::
get_first_input
()
{
return
get_input
(
0
);
}
std
::
vector
<
PredictorOutput
>
PPredictor
::
infer
()
{
LOGI
(
"infer Run start %d"
,
_net_flag
);
LOGI
(
"
ocr cpp
infer Run start %d"
,
_net_flag
);
std
::
vector
<
PredictorOutput
>
results
;
if
(
!
_is_input_get
)
{
return
results
;
}
_predictor
->
Run
();
LOGI
(
"infer Run end"
);
LOGI
(
"
ocr cpp
infer Run end"
);
for
(
int
i
=
0
;
i
<
_predictor
->
GetOutputNames
().
size
();
i
++
)
{
std
::
unique_ptr
<
const
paddle
::
lite_api
::
Tensor
>
output_tensor
=
_predictor
->
GetOutput
(
i
);
LOGI
(
"output tensor[%d] size %ld"
,
i
,
product
(
output_tensor
->
shape
()));
LOGI
(
"
ocr cpp
output tensor[%d] size %ld"
,
i
,
product
(
output_tensor
->
shape
()));
PredictorOutput
result
{
std
::
move
(
output_tensor
),
i
,
_net_flag
};
results
.
emplace_back
(
std
::
move
(
result
));
}
...
...
deploy/android_demo/app/src/main/cpp/ppredictor.h
View file @
191c9dee
...
...
@@ -22,7 +22,7 @@ public:
class
PPredictor
:
public
PPredictor_Interface
{
public:
PPredictor
(
int
thread_num
,
int
net_flag
=
0
,
int
use_opencl
,
int
thread_num
,
int
net_flag
=
0
,
paddle
::
lite_api
::
PowerMode
mode
=
paddle
::
lite_api
::
LITE_POWER_HIGH
);
virtual
~
PPredictor
()
{}
...
...
@@ -54,6 +54,7 @@ protected:
template
<
typename
ConfigT
>
int
_init
(
ConfigT
&
config
);
private:
int
_use_opencl
;
int
_thread_num
;
paddle
::
lite_api
::
PowerMode
_mode
;
std
::
shared_ptr
<
paddle
::
lite_api
::
PaddlePredictor
>
_predictor
;
...
...
deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/MainActivity.java
View file @
191c9dee
...
...
@@ -13,6 +13,7 @@ import android.graphics.BitmapFactory;
import
android.graphics.drawable.BitmapDrawable
;
import
android.media.ExifInterface
;
import
android.content.res.AssetManager
;
import
android.media.FaceDetector
;
import
android.net.Uri
;
import
android.os.Bundle
;
import
android.os.Environment
;
...
...
@@ -27,7 +28,9 @@ import android.view.Menu;
import
android.view.MenuInflater
;
import
android.view.MenuItem
;
import
android.view.View
;
import
android.widget.CheckBox
;
import
android.widget.ImageView
;
import
android.widget.Spinner
;
import
android.widget.TextView
;
import
android.widget.Toast
;
...
...
@@ -68,23 +71,24 @@ public class MainActivity extends AppCompatActivity {
protected
ImageView
ivInputImage
;
protected
TextView
tvOutputResult
;
protected
TextView
tvInferenceTime
;
protected
CheckBox
cbOpencl
;
protected
Spinner
spRunMode
;
// Model settings of o
bject detection
// Model settings of o
cr
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
int
detLongSize
=
960
;
protected
float
scoreThreshold
=
0.1f
;
private
String
currentPhotoPath
;
private
AssetManager
assetManager
=
null
;
private
AssetManager
assetManager
=
null
;
protected
Predictor
predictor
=
new
Predictor
();
private
Bitmap
cur_predict_image
=
null
;
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
...
...
@@ -98,10 +102,12 @@ public class MainActivity extends AppCompatActivity {
// Setup the UI components
tvInputSetting
=
findViewById
(
R
.
id
.
tv_input_setting
);
cbOpencl
=
findViewById
(
R
.
id
.
cb_opencl
);
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
);
spRunMode
=
findViewById
(
R
.
id
.
sp_run_mode
);
tvInputSetting
.
setMovementMethod
(
ScrollingMovementMethod
.
getInstance
());
tvOutputResult
.
setMovementMethod
(
ScrollingMovementMethod
.
getInstance
());
...
...
@@ -111,26 +117,26 @@ public class MainActivity extends AppCompatActivity {
public
void
handleMessage
(
Message
msg
)
{
switch
(
msg
.
what
)
{
case
RESPONSE_LOAD_MODEL_SUCCESSED:
if
(
pbLoadModel
!=
null
&&
pbLoadModel
.
isShowing
()){
if
(
pbLoadModel
!=
null
&&
pbLoadModel
.
isShowing
())
{
pbLoadModel
.
dismiss
();
}
onLoadModelSuccessed
();
break
;
case
RESPONSE_LOAD_MODEL_FAILED:
if
(
pbLoadModel
!=
null
&&
pbLoadModel
.
isShowing
()){
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
()){
if
(
pbRunModel
!=
null
&&
pbRunModel
.
isShowing
())
{
pbRunModel
.
dismiss
();
}
onRunModelSuccessed
();
break
;
case
RESPONSE_RUN_MODEL_FAILED:
if
(
pbRunModel
!=
null
&&
pbRunModel
.
isShowing
()){
if
(
pbRunModel
!=
null
&&
pbRunModel
.
isShowing
())
{
pbRunModel
.
dismiss
();
}
Toast
.
makeText
(
MainActivity
.
this
,
"Run model failed!"
,
Toast
.
LENGTH_SHORT
).
show
();
...
...
@@ -175,71 +181,47 @@ public class MainActivity extends AppCompatActivity {
super
.
onResume
();
SharedPreferences
sharedPreferences
=
PreferenceManager
.
getDefaultSharedPreferences
(
this
);
boolean
settingsChanged
=
false
;
boolean
model_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
);
model_
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
;
model_
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
];
}
}
model_settingsChanged
|=
!
cpu_power_mode
.
equalsIgnoreCase
(
cpuPowerMode
);
int
det_long_size
=
Integer
.
parseInt
(
sharedPreferences
.
getString
(
getString
(
R
.
string
.
DET_LONG_SIZE_KEY
),
getString
(
R
.
string
.
DET_LONG_SIZE_DEFAULT
)));
settingsChanged
|=
det_long_size
!=
detLongSize
;
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
;
detLongSize
=
det_long_size
;
scoreThreshold
=
score_threshold
;
set_img
();
}
if
(
model_settingsChanged
)
{
modelPath
=
model_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
.
setText
(
"Model: "
+
modelPath
.
substring
(
modelPath
.
lastIndexOf
(
"/"
)
+
1
)
+
"\nOPENCL: "
+
cbOpencl
.
isChecked
()
+
"\nCPU Thread Num: "
+
cpuThreadNum
+
"\nCPU Power Mode: "
+
cpuPowerMode
);
tvInputSetting
.
scrollTo
(
0
,
0
);
// Reload model if configure has been changed
// loadModel();
set_img
();
loadModel
();
}
}
...
...
@@ -254,20 +236,28 @@ public class MainActivity extends AppCompatActivity {
}
public
boolean
onLoadModel
()
{
return
predictor
.
init
(
MainActivity
.
this
,
modelPath
,
labelPath
,
cpuThreadNum
,
if
(
predictor
.
isLoaded
())
{
predictor
.
releaseModel
();
}
return
predictor
.
init
(
MainActivity
.
this
,
modelPath
,
labelPath
,
cbOpencl
.
isChecked
()
?
1
:
0
,
cpuThreadNum
,
cpuPowerMode
,
inputColorFormat
,
inputShape
,
inputMean
,
inputStd
,
scoreThreshold
);
detLongSize
,
scoreThreshold
);
}
public
boolean
onRunModel
()
{
return
predictor
.
isLoaded
()
&&
predictor
.
runModel
();
String
run_mode
=
spRunMode
.
getSelectedItem
().
toString
();
int
run_det
=
run_mode
.
contains
(
"检测"
)
?
1
:
0
;
int
run_cls
=
run_mode
.
contains
(
"分类"
)
?
1
:
0
;
int
run_rec
=
run_mode
.
contains
(
"识别"
)
?
1
:
0
;
return
predictor
.
isLoaded
()
&&
predictor
.
runModel
(
run_det
,
run_cls
,
run_rec
);
}
public
void
onLoadModelSuccessed
()
{
// Load test image from path and run model
tvInputSetting
.
setText
(
"Model: "
+
modelPath
.
substring
(
modelPath
.
lastIndexOf
(
"/"
)
+
1
)
+
"\nOPENCL: "
+
cbOpencl
.
isChecked
()
+
"\nCPU Thread Num: "
+
cpuThreadNum
+
"\nCPU Power Mode: "
+
cpuPowerMode
);
tvInputSetting
.
scrollTo
(
0
,
0
);
tvStatus
.
setText
(
"STATUS: load model successed"
);
}
public
void
onLoadModelFailed
()
{
...
...
@@ -290,20 +280,13 @@ public class MainActivity extends AppCompatActivity {
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
);
assetManager
=
getAssets
();
InputStream
in
=
assetManager
.
open
(
imagePath
);
Bitmap
bmp
=
BitmapFactory
.
decodeStream
(
in
);
cur_predict_image
=
bmp
;
ivInputImage
.
setImageBitmap
(
bmp
);
}
catch
(
IOException
e
)
{
Toast
.
makeText
(
MainActivity
.
this
,
"Load image failed!"
,
Toast
.
LENGTH_SHORT
).
show
();
...
...
@@ -430,7 +413,7 @@ public class MainActivity extends AppCompatActivity {
Cursor
cursor
=
managedQuery
(
uri
,
proj
,
null
,
null
,
null
);
cursor
.
moveToFirst
();
if
(
image
!=
null
)
{
//
onImageChanged(
image
)
;
cur_predict_image
=
image
;
ivInputImage
.
setImageBitmap
(
image
);
}
}
catch
(
IOException
e
)
{
...
...
@@ -451,7 +434,7 @@ public class MainActivity extends AppCompatActivity {
Bitmap
image
=
BitmapFactory
.
decodeFile
(
currentPhotoPath
);
image
=
Utils
.
rotateBitmap
(
image
,
orientation
);
if
(
image
!=
null
)
{
//
onImageChanged(
image
)
;
cur_predict_image
=
image
;
ivInputImage
.
setImageBitmap
(
image
);
}
}
else
{
...
...
@@ -464,28 +447,28 @@ public class MainActivity extends AppCompatActivity {
}
}
public
void
btn_load_model_click
(
View
view
)
{
if
(
predictor
.
isLoaded
()){
tvStatus
.
setText
(
"STATUS: model has been loaded"
);
}
else
{
public
void
btn_reset_img_click
(
View
view
)
{
ivInputImage
.
setImageBitmap
(
cur_predict_image
);
}
public
void
cb_opencl_click
(
View
view
)
{
tvStatus
.
setText
(
"STATUS: load model ......"
);
loadModel
();
}
}
public
void
btn_run_model_click
(
View
view
)
{
Bitmap
image
=((
BitmapDrawable
)
ivInputImage
.
getDrawable
()).
getBitmap
();
if
(
image
==
null
)
{
Bitmap
image
=
((
BitmapDrawable
)
ivInputImage
.
getDrawable
()).
getBitmap
();
if
(
image
==
null
)
{
tvStatus
.
setText
(
"STATUS: image is not exists"
);
}
else
if
(!
predictor
.
isLoaded
()){
}
else
if
(!
predictor
.
isLoaded
())
{
tvStatus
.
setText
(
"STATUS: model is not loaded"
);
}
else
{
}
else
{
tvStatus
.
setText
(
"STATUS: run model ...... "
);
predictor
.
setInputImage
(
image
);
runModel
();
}
}
public
void
btn_choice_img_click
(
View
view
)
{
if
(
requestAllPermissions
())
{
openGallery
();
...
...
@@ -506,4 +489,32 @@ public class MainActivity extends AppCompatActivity {
worker
.
quit
();
super
.
onDestroy
();
}
public
int
get_run_mode
()
{
String
run_mode
=
spRunMode
.
getSelectedItem
().
toString
();
int
mode
;
switch
(
run_mode
)
{
case
"检测+分类+识别"
:
mode
=
1
;
break
;
case
"检测+识别"
:
mode
=
2
;
break
;
case
"识别+分类"
:
mode
=
3
;
break
;
case
"检测"
:
mode
=
4
;
break
;
case
"识别"
:
mode
=
5
;
break
;
case
"分类"
:
mode
=
6
;
break
;
default
:
mode
=
1
;
}
return
mode
;
}
}
deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/MiniActivity.java
deleted
100644 → 0
View file @
3c6d5512
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
View file @
191c9dee
...
...
@@ -29,22 +29,22 @@ public class OCRPredictorNative {
public
OCRPredictorNative
(
Config
config
)
{
this
.
config
=
config
;
loadLibrary
();
nativePointer
=
init
(
config
.
detModelFilename
,
config
.
recModelFilename
,
config
.
clsModelFilename
,
nativePointer
=
init
(
config
.
detModelFilename
,
config
.
recModelFilename
,
config
.
clsModelFilename
,
config
.
useOpencl
,
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
);
public
ArrayList
<
OcrResultModel
>
runImage
(
Bitmap
originalImage
,
int
max_size_len
,
int
run_det
,
int
run_cls
,
int
run_rec
)
{
Log
.
i
(
"OCRPredictorNative"
,
"begin to run image "
);
float
[]
rawResults
=
forward
(
nativePointer
,
originalImage
,
max_size_len
,
run_det
,
run_cls
,
run_rec
);
ArrayList
<
OcrResultModel
>
results
=
postprocess
(
rawResults
);
return
results
;
}
public
static
class
Config
{
public
int
useOpencl
;
public
int
cpuThreadNum
;
public
String
cpuPower
;
public
String
detModelFilename
;
...
...
@@ -53,16 +53,16 @@ public class OCRPredictorNative {
}
public
void
destory
(){
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
long
init
(
String
detModelPath
,
String
recModelPath
,
String
clsModelPath
,
int
useOpencl
,
int
threadNum
,
String
cpuMode
);
protected
native
float
[]
forward
(
long
pointer
,
float
[]
buf
,
float
[]
ddims
,
Bitmap
originalImage
);
protected
native
float
[]
forward
(
long
pointer
,
Bitmap
originalImage
,
int
max_size_len
,
int
run_det
,
int
run_cls
,
int
run_rec
);
protected
native
void
release
(
long
pointer
);
...
...
@@ -73,9 +73,9 @@ public class OCRPredictorNative {
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
);
OcrResultModel
res
=
parse
(
raw
,
begin
+
2
,
point_num
,
word_num
);
begin
+=
2
+
1
+
point_num
*
2
+
word_num
+
2
;
results
.
add
(
res
);
}
return
results
;
...
...
@@ -83,19 +83,22 @@ public class OCRPredictorNative {
private
OcrResultModel
parse
(
float
[]
raw
,
int
begin
,
int
pointNum
,
int
wordNum
)
{
int
current
=
begin
;
OcrResultModel
model
=
new
OcrResultModel
();
model
.
setConfidence
(
raw
[
current
]);
OcrResultModel
res
=
new
OcrResultModel
();
res
.
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
]));
res
.
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
);
res
.
addWordIndex
(
index
);
}
current
+=
wordNum
;
res
.
setClsIdx
(
raw
[
current
]);
res
.
setClsConfidence
(
raw
[
current
+
1
]);
Log
.
i
(
"OCRPredictorNative"
,
"word finished "
+
wordNum
);
return
model
;
return
res
;
}
...
...
deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/OcrResultModel.java
View file @
191c9dee
...
...
@@ -10,6 +10,9 @@ public class OcrResultModel {
private
List
<
Integer
>
wordIndex
;
private
String
label
;
private
float
confidence
;
private
float
cls_idx
;
private
String
cls_label
;
private
float
cls_confidence
;
public
OcrResultModel
()
{
super
();
...
...
@@ -49,4 +52,28 @@ public class OcrResultModel {
public
void
setConfidence
(
float
confidence
)
{
this
.
confidence
=
confidence
;
}
public
float
getClsIdx
()
{
return
cls_idx
;
}
public
void
setClsIdx
(
float
idx
)
{
this
.
cls_idx
=
idx
;
}
public
String
getClsLabel
()
{
return
cls_label
;
}
public
void
setClsLabel
(
String
label
)
{
this
.
cls_label
=
label
;
}
public
float
getClsConfidence
()
{
return
cls_confidence
;
}
public
void
setClsConfidence
(
float
confidence
)
{
this
.
cls_confidence
=
confidence
;
}
}
deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/Predictor.java
View file @
191c9dee
...
...
@@ -31,23 +31,19 @@ public class Predictor {
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
int
detLongSize
=
960
;
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
);
public
boolean
init
(
Context
appCtx
,
String
modelPath
,
String
labelPath
,
int
useOpencl
,
int
cpuThreadNum
,
String
cpuPowerMode
)
{
isLoaded
=
loadModel
(
appCtx
,
modelPath
,
useOpencl
,
cpuThreadNum
,
cpuPowerMode
);
if
(!
isLoaded
)
{
return
false
;
}
...
...
@@ -56,49 +52,18 @@ public class Predictor {
}
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
);
public
boolean
init
(
Context
appCtx
,
String
modelPath
,
String
labelPath
,
int
useOpencl
,
int
cpuThreadNum
,
String
cpuPowerMode
,
int
detLongSize
,
float
scoreThreshold
)
{
boolean
isLoaded
=
init
(
appCtx
,
modelPath
,
labelPath
,
useOpencl
,
cpuThreadNum
,
cpuPowerMode
);
if
(!
isLoaded
)
{
return
false
;
}
this
.
inputColorFormat
=
inputColorFormat
;
this
.
inputShape
=
inputShape
;
this
.
inputMean
=
inputMean
;
this
.
inputStd
=
inputStd
;
this
.
detLongSize
=
detLongSize
;
this
.
scoreThreshold
=
scoreThreshold
;
return
true
;
}
protected
boolean
loadModel
(
Context
appCtx
,
String
modelPath
,
int
cpuThreadNum
,
String
cpuPowerMode
)
{
protected
boolean
loadModel
(
Context
appCtx
,
String
modelPath
,
int
useOpencl
,
int
cpuThreadNum
,
String
cpuPowerMode
)
{
// Release model if exists
releaseModel
();
...
...
@@ -118,12 +83,13 @@ public class Predictor {
}
OCRPredictorNative
.
Config
config
=
new
OCRPredictorNative
.
Config
();
config
.
useOpencl
=
useOpencl
;
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
;
config
.
detModelFilename
=
realPath
+
File
.
separator
+
"det_db.nb"
;
config
.
recModelFilename
=
realPath
+
File
.
separator
+
"rec_crnn.nb"
;
config
.
clsModelFilename
=
realPath
+
File
.
separator
+
"cls.nb"
;
Log
.
i
(
"Predictor"
,
"model path"
+
config
.
detModelFilename
+
" ; "
+
config
.
recModelFilename
+
";"
+
config
.
clsModelFilename
);
paddlePredictor
=
new
OCRPredictorNative
(
config
);
this
.
cpuThreadNum
=
cpuThreadNum
;
...
...
@@ -170,82 +136,29 @@ public class Predictor {
}
public
boolean
runModel
()
{
public
boolean
runModel
(
int
run_det
,
int
run_cls
,
int
run_rec
)
{
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
(
input
Data
,
width
,
height
,
channels
,
inputImage
);
paddlePredictor
.
runImage
(
input
Image
,
detLongSize
,
run_det
,
run_cls
,
run_rec
);
}
warmupIterNum
=
0
;
// do not need warm
// Run inference
start
=
new
Date
();
ArrayList
<
OcrResultModel
>
results
=
paddlePredictor
.
runImage
(
input
Data
,
width
,
height
,
channels
,
inputImage
);
end
=
new
Date
();
Date
start
=
new
Date
();
ArrayList
<
OcrResultModel
>
results
=
paddlePredictor
.
runImage
(
input
Image
,
detLongSize
,
run_det
,
run_cls
,
run_rec
);
Date
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
());
Log
.
i
(
TAG
,
"[stat] Inference Time: "
+
inferenceTime
+
" ;Box Size "
+
results
.
size
());
drawResults
(
results
);
return
true
;
}
public
boolean
isLoaded
()
{
return
paddlePredictor
!=
null
&&
isLoaded
;
}
...
...
@@ -282,10 +195,6 @@ public class Predictor {
return
outputResult
;
}
public
float
preprocessTime
()
{
return
preprocessTime
;
}
public
float
postprocessTime
()
{
return
postprocessTime
;
}
...
...
@@ -310,6 +219,7 @@ public class Predictor {
}
}
r
.
setLabel
(
word
.
toString
());
r
.
setClsLabel
(
r
.
getClsIdx
()
==
1
?
"180"
:
"0"
);
}
return
results
;
}
...
...
@@ -319,14 +229,22 @@ public class Predictor {
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: "
);
if
(
result
.
getPoints
().
size
()>
0
){
sb
.
append
(
"Det: "
);
for
(
Point
p
:
result
.
getPoints
())
{
sb
.
append
(
"("
).
append
(
p
.
x
).
append
(
","
).
append
(
p
.
y
).
append
(
") "
);
}
}
if
(
result
.
getLabel
().
length
()
>
0
){
sb
.
append
(
"\n Rec: "
).
append
(
result
.
getLabel
());
sb
.
append
(
","
).
append
(
result
.
getConfidence
());
}
if
(
result
.
getClsIdx
()!=-
1
){
sb
.
append
(
" Cls: "
).
append
(
result
.
getClsLabel
());
sb
.
append
(
","
).
append
(
result
.
getClsConfidence
());
}
Log
.
i
(
TAG
,
sb
.
toString
());
// show LOG in Logcat panel
outputResultSb
.
append
(
i
+
1
).
append
(
": "
).
append
(
result
.
getLabel
()).
append
(
"\n"
);
outputResultSb
.
append
(
i
+
1
).
append
(
": "
).
append
(
sb
.
toString
()).
append
(
"\n"
);
}
outputResult
=
outputResultSb
.
toString
();
outputImage
=
inputImage
;
...
...
@@ -344,6 +262,9 @@ public class Predictor {
for
(
OcrResultModel
result
:
results
)
{
Path
path
=
new
Path
();
List
<
Point
>
points
=
result
.
getPoints
();
if
(
points
.
size
()==
0
){
continue
;
}
path
.
moveTo
(
points
.
get
(
0
).
x
,
points
.
get
(
0
).
y
);
for
(
int
i
=
points
.
size
()
-
1
;
i
>=
0
;
i
--)
{
Point
p
=
points
.
get
(
i
);
...
...
deploy/android_demo/app/src/main/java/com/baidu/paddle/lite/demo/ocr/SettingsActivity.java
View file @
191c9dee
...
...
@@ -20,16 +20,13 @@ public class SettingsActivity extends AppCompatPreferenceActivity implements Sha
ListPreference
etImagePath
=
null
;
ListPreference
lpCPUThreadNum
=
null
;
ListPreference
lpCPUPowerMode
=
null
;
ListPreference
lpInputColorFormat
=
null
;
EditTextPreference
etInputShape
=
null
;
EditTextPreference
etInputMean
=
null
;
EditTextPreference
etInputStd
=
null
;
EditTextPreference
etDetLongSize
=
null
;
EditTextPreference
etScoreThreshold
=
null
;
List
<
String
>
preInstalledModelPaths
=
null
;
List
<
String
>
preInstalledLabelPaths
=
null
;
List
<
String
>
preInstalledImagePaths
=
null
;
List
<
String
>
preInstalled
InputShap
es
=
null
;
List
<
String
>
preInstalled
DetLongSiz
es
=
null
;
List
<
String
>
preInstalledCPUThreadNums
=
null
;
List
<
String
>
preInstalledCPUPowerModes
=
null
;
List
<
String
>
preInstalledInputColorFormats
=
null
;
...
...
@@ -50,7 +47,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity implements Sha
preInstalledModelPaths
=
new
ArrayList
<
String
>();
preInstalledLabelPaths
=
new
ArrayList
<
String
>();
preInstalledImagePaths
=
new
ArrayList
<
String
>();
preInstalled
InputShap
es
=
new
ArrayList
<
String
>();
preInstalled
DetLongSiz
es
=
new
ArrayList
<
String
>();
preInstalledCPUThreadNums
=
new
ArrayList
<
String
>();
preInstalledCPUPowerModes
=
new
ArrayList
<
String
>();
preInstalledInputColorFormats
=
new
ArrayList
<
String
>();
...
...
@@ -63,10 +60,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity implements Sha
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
));
preInstalledDetLongSizes
.
add
(
getString
(
R
.
string
.
DET_LONG_SIZE_DEFAULT
));
preInstalledScoreThresholds
.
add
(
getString
(
R
.
string
.
SCORE_THRESHOLD_DEFAULT
));
// Setup UI components
...
...
@@ -89,11 +83,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity implements Sha
(
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
));
etDetLongSize
=
(
EditTextPreference
)
findPreference
(
getString
(
R
.
string
.
DET_LONG_SIZE_KEY
));
etScoreThreshold
=
(
EditTextPreference
)
findPreference
(
getString
(
R
.
string
.
SCORE_THRESHOLD_KEY
));
}
...
...
@@ -112,11 +102,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity implements Sha
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
.
DET_LONG_SIZE_KEY
),
preInstalledDetLongSizes
.
get
(
modelIdx
));
editor
.
putString
(
getString
(
R
.
string
.
SCORE_THRESHOLD_KEY
),
preInstalledScoreThresholds
.
get
(
modelIdx
));
editor
.
apply
();
...
...
@@ -129,10 +115,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity implements Sha
etImagePath
.
setEnabled
(
enableCustomSettings
);
lpCPUThreadNum
.
setEnabled
(
enableCustomSettings
);
lpCPUPowerMode
.
setEnabled
(
enableCustomSettings
);
lpInputColorFormat
.
setEnabled
(
enableCustomSettings
);
etInputShape
.
setEnabled
(
enableCustomSettings
);
etInputMean
.
setEnabled
(
enableCustomSettings
);
etInputStd
.
setEnabled
(
enableCustomSettings
);
etDetLongSize
.
setEnabled
(
enableCustomSettings
);
etScoreThreshold
.
setEnabled
(
enableCustomSettings
);
modelPath
=
sharedPreferences
.
getString
(
getString
(
R
.
string
.
MODEL_PATH_KEY
),
getString
(
R
.
string
.
MODEL_PATH_DEFAULT
));
...
...
@@ -144,14 +127,8 @@ public class SettingsActivity extends AppCompatPreferenceActivity implements Sha
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
detLongSize
=
sharedPreferences
.
getString
(
getString
(
R
.
string
.
DET_LONG_SIZE_KEY
),
getString
(
R
.
string
.
DET_LONG_SIZE_DEFAULT
));
String
scoreThreshold
=
sharedPreferences
.
getString
(
getString
(
R
.
string
.
SCORE_THRESHOLD_KEY
),
getString
(
R
.
string
.
SCORE_THRESHOLD_DEFAULT
));
etModelPath
.
setSummary
(
modelPath
);
...
...
@@ -164,14 +141,8 @@ public class SettingsActivity extends AppCompatPreferenceActivity implements Sha
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
);
etDetLongSize
.
setSummary
(
detLongSize
);
etDetLongSize
.
setText
(
detLongSize
);
etScoreThreshold
.
setText
(
scoreThreshold
);
etScoreThreshold
.
setSummary
(
scoreThreshold
);
}
...
...
deploy/android_demo/app/src/main/res/layout/activity_main.xml
View file @
191c9dee
...
...
@@ -23,13 +23,7 @@
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"
...
...
@@ -52,7 +46,45 @@
android:onClick=
"btn_choice_img_click"
android:text=
"选取图片"
/>
<Button
android:id=
"@+id/btn_reset_img"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_weight=
"1"
android:onClick=
"btn_reset_img_click"
android:text=
"清空绘图"
/>
</LinearLayout>
<LinearLayout
android:id=
"@+id/run_mode_layout"
android:layout_width=
"fill_parent"
android:layout_height=
"wrap_content"
android:orientation=
"horizontal"
>
<CheckBox
android:id=
"@+id/cb_opencl"
android:layout_width=
"0dp"
android:layout_weight=
"1"
android:layout_height=
"wrap_content"
android:text=
"开启OPENCL"
android:onClick=
"cb_opencl_click"
android:visibility=
"gone"
/>
<TextView
android:layout_width=
"0dp"
android:layout_weight=
"0.5"
android:layout_height=
"wrap_content"
android:text=
"运行模式:"
/>
<Spinner
android:id=
"@+id/sp_run_mode"
android:layout_width=
"0dp"
android:layout_weight=
"1.5"
android:layout_height=
"wrap_content"
android:entries=
"@array/run_Model"
/>
</LinearLayout>
<TextView
android:id=
"@+id/tv_input_setting"
android:layout_width=
"wrap_content"
...
...
@@ -60,7 +92,7 @@
android:scrollbars=
"vertical"
android:layout_marginLeft=
"12dp"
android:layout_marginRight=
"12dp"
android:layout_marginTop=
"
10
dp"
android:layout_marginTop=
"
5
dp"
android:layout_marginBottom=
"5dp"
android:lineSpacingExtra=
"4dp"
android:singleLine=
"false"
...
...
deploy/android_demo/app/src/main/res/layout/activity_mini.xml
deleted
100644 → 0
View file @
3c6d5512
<?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/values/arrays.xml
View file @
191c9dee
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array
name=
"image_name_entries"
>
<item>
0.jpg
</item>
<item>
90.jpg
</item>
<item>
180.jpg
</item>
<item>
270.jpg
</item>
<item>
det_0.jpg
</item>
<item>
det_90.jpg
</item>
<item>
det_180.jpg
</item>
<item>
det_270.jpg
</item>
<item>
rec_0.jpg
</item>
<item>
rec_0_180.jpg
</item>
<item>
rec_1.jpg
</item>
<item>
rec_1_180.jpg
</item>
</string-array>
<string-array
name=
"image_name_values"
>
<item>
images/0.jpg
</item>
<item>
images/90.jpg
</item>
<item>
images/180.jpg
</item>
<item>
images/270.jpg
</item>
<item>
images/det_0.jpg
</item>
<item>
images/det_90.jpg
</item>
<item>
images/det_180.jpg
</item>
<item>
images/det_270.jpg
</item>
<item>
images/rec_0.jpg
</item>
<item>
images/rec_0_180.jpg
</item>
<item>
images/rec_1.jpg
</item>
<item>
images/rec_1_180.jpg
</item>
</string-array>
<string-array
name=
"cpu_thread_num_entries"
>
<item>
1 threads
</item>
...
...
@@ -48,4 +56,12 @@
<item>
BGR
</item>
<item>
RGB
</item>
</string-array>
<string-array
name=
"run_Model"
>
<item>
检测+分类+识别
</item>
<item>
检测+识别
</item>
<item>
分类+识别
</item>
<item>
检测
</item>
<item>
识别
</item>
<item>
分类
</item>
</string-array>
</resources>
\ No newline at end of file
deploy/android_demo/app/src/main/res/values/strings.xml
View file @
191c9dee
<resources>
<string
name=
"app_name"
>
OCR Chinese
</string>
<string
name=
"app_name"
>
PaddleOCR
</string>
<string
name=
"CHOOSE_PRE_INSTALLED_MODEL_KEY"
>
CHOOSE_PRE_INSTALLED_MODEL_KEY
</string>
<string
name=
"ENABLE_CUSTOM_SETTINGS_KEY"
>
ENABLE_CUSTOM_SETTINGS_KEY
</string>
<string
name=
"MODEL_PATH_KEY"
>
MODEL_PATH_KEY
</string>
...
...
@@ -7,20 +7,14 @@
<string
name=
"IMAGE_PATH_KEY"
>
IMAGE_PATH_KEY
</string>
<string
name=
"CPU_THREAD_NUM_KEY"
>
CPU_THREAD_NUM_KEY
</string>
<string
name=
"CPU_POWER_MODE_KEY"
>
CPU_POWER_MODE_KEY
</string>
<string
name=
"INPUT_COLOR_FORMAT_KEY"
>
INPUT_COLOR_FORMAT_KEY
</string>
<string
name=
"INPUT_SHAPE_KEY"
>
INPUT_SHAPE_KEY
</string>
<string
name=
"INPUT_MEAN_KEY"
>
INPUT_MEAN_KEY
</string>
<string
name=
"INPUT_STD_KEY"
>
INPUT_STD_KEY
</string>
<string
name=
"DET_LONG_SIZE_KEY"
>
DET_LONG_SIZE_KEY
</string>
<string
name=
"SCORE_THRESHOLD_KEY"
>
SCORE_THRESHOLD_KEY
</string>
<string
name=
"MODEL_PATH_DEFAULT"
>
models/
ocr_v2_for_cpu
</string>
<string
name=
"MODEL_PATH_DEFAULT"
>
models/
ch_PP-OCRv2
</string>
<string
name=
"LABEL_PATH_DEFAULT"
>
labels/ppocr_keys_v1.txt
</string>
<string
name=
"IMAGE_PATH_DEFAULT"
>
images/0.jpg
</string>
<string
name=
"IMAGE_PATH_DEFAULT"
>
images/
det_
0.jpg
</string>
<string
name=
"CPU_THREAD_NUM_DEFAULT"
>
4
</string>
<string
name=
"CPU_POWER_MODE_DEFAULT"
>
LITE_POWER_HIGH
</string>
<string
name=
"INPUT_COLOR_FORMAT_DEFAULT"
>
BGR
</string>
<string
name=
"INPUT_SHAPE_DEFAULT"
>
1,3,960
</string>
<string
name=
"INPUT_MEAN_DEFAULT"
>
0.485, 0.456, 0.406
</string>
<string
name=
"INPUT_STD_DEFAULT"
>
0.229,0.224,0.225
</string>
<string
name=
"DET_LONG_SIZE_DEFAULT"
>
960
</string>
<string
name=
"SCORE_THRESHOLD_DEFAULT"
>
0.1
</string>
</resources>
deploy/android_demo/app/src/main/res/xml/settings.xml
View file @
191c9dee
...
...
@@ -47,26 +47,10 @@
android:entryValues=
"@array/cpu_power_mode_values"
/>
</PreferenceCategory>
<PreferenceCategory
android:title=
"Input Settings"
>
<ListPreference
android:defaultValue=
"@string/INPUT_COLOR_FORMAT_DEFAULT"
android:key=
"@string/INPUT_COLOR_FORMAT_KEY"
android:negativeButtonText=
"@null"
android:positiveButtonText=
"@null"
android:title=
"Input Color Format: BGR or RGB"
android:entries=
"@array/input_color_format_entries"
android:entryValues=
"@array/input_color_format_values"
/>
<EditTextPreference
android:key=
"@string/INPUT_SHAPE_KEY"
android:defaultValue=
"@string/INPUT_SHAPE_DEFAULT"
android:title=
"Input Shape: (1,1,max_width_height) or (1,3,max_width_height)"
/>
<EditTextPreference
android:key=
"@string/INPUT_MEAN_KEY"
android:defaultValue=
"@string/INPUT_MEAN_DEFAULT"
android:title=
"Input Mean: (channel/255-mean)/std"
/>
<EditTextPreference
android:key=
"@string/
INPUT_STD
_KEY"
android:defaultValue=
"@string/
INPUT_STD
_DEFAULT"
android:title=
"
Input Std: (channel/255-mean)/std
"
/>
android:key=
"@string/
DET_LONG_SIZE
_KEY"
android:defaultValue=
"@string/
DET_LONG_SIZE
_DEFAULT"
android:title=
"
det long size
"
/>
</PreferenceCategory>
<PreferenceCategory
android:title=
"Output Settings"
>
<EditTextPreference
...
...
deploy/cpp_infer/include/ocr_det.h
View file @
191c9dee
...
...
@@ -45,8 +45,9 @@ public:
const
double
&
det_db_thresh
,
const
double
&
det_db_box_thresh
,
const
double
&
det_db_unclip_ratio
,
const
bool
&
use_polygon_score
,
const
bool
&
visualize
,
const
bool
&
use_tensorrt
,
const
std
::
string
&
precision
)
{
const
bool
&
use_polygon_score
,
const
bool
&
use_dilation
,
const
bool
&
visualize
,
const
bool
&
use_tensorrt
,
const
std
::
string
&
precision
)
{
this
->
use_gpu_
=
use_gpu
;
this
->
gpu_id_
=
gpu_id
;
this
->
gpu_mem_
=
gpu_mem
;
...
...
@@ -59,6 +60,7 @@ public:
this
->
det_db_box_thresh_
=
det_db_box_thresh
;
this
->
det_db_unclip_ratio_
=
det_db_unclip_ratio
;
this
->
use_polygon_score_
=
use_polygon_score
;
this
->
use_dilation_
=
use_dilation
;
this
->
visualize_
=
visualize
;
this
->
use_tensorrt_
=
use_tensorrt
;
...
...
@@ -71,7 +73,8 @@ public:
void
LoadModel
(
const
std
::
string
&
model_dir
);
// Run predictor
void
Run
(
cv
::
Mat
&
img
,
std
::
vector
<
std
::
vector
<
std
::
vector
<
int
>>>
&
boxes
,
std
::
vector
<
double
>
*
times
);
void
Run
(
cv
::
Mat
&
img
,
std
::
vector
<
std
::
vector
<
std
::
vector
<
int
>>>
&
boxes
,
std
::
vector
<
double
>
*
times
);
private:
std
::
shared_ptr
<
Predictor
>
predictor_
;
...
...
@@ -88,6 +91,7 @@ private:
double
det_db_box_thresh_
=
0.5
;
double
det_db_unclip_ratio_
=
2.0
;
bool
use_polygon_score_
=
false
;
bool
use_dilation_
=
false
;
bool
visualize_
=
true
;
bool
use_tensorrt_
=
false
;
...
...
deploy/cpp_infer/readme.md
View file @
191c9dee
...
...
@@ -4,16 +4,20 @@
C++在性能计算上优于python,因此,在大多数CPU、GPU部署场景,多采用C++的部署方式,本节将介绍如何在Linux
\W
indows (CPU
\G
PU)环境下配置C++环境并完成
PaddleOCR模型部署。
*
[
1. 准备环境
](
#1
)
+
[
1.0 运行准备
](
#10
)
+
[
1.1 编译opencv库
](
#11
)
+
[
1.2 下载或者编译Paddle预测库
](
#12
)
-
[
1.2.1 直接下载安装
](
#121
)
-
[
1.2.2 预测库源码编译
](
#122
)
*
[
2 开始运行
](
#2
)
+
[
2.1 将模型导出为inference model
](
#21
)
+
[
2.2 编译PaddleOCR C++预测demo
](
#22
)
+
[
2.3运行demo
](
#23
)
-
[
服务器端C++预测
](
#服务器端c预测
)
-
[
1. 准备环境
](
#1-准备环境
)
-
[
1.0 运行准备
](
#10-运行准备
)
-
[
1.1 编译opencv库
](
#11-编译opencv库
)
-
[
1.2 下载或者编译Paddle预测库
](
#12-下载或者编译paddle预测库
)
-
[
1.2.1 直接下载安装
](
#121-直接下载安装
)
-
[
1.2.2 预测库源码编译
](
#122-预测库源码编译
)
-
[
2 开始运行
](
#2-开始运行
)
-
[
2.1 将模型导出为inference model
](
#21-将模型导出为inference-model
)
-
[
2.2 编译PaddleOCR C++预测demo
](
#22-编译paddleocr-c预测demo
)
-
[
2.3 运行demo
](
#23-运行demo
)
-
[
1. 只调用检测:
](
#1-只调用检测
)
-
[
2. 只调用识别:
](
#2-只调用识别
)
-
[
3. 调用串联:
](
#3-调用串联
)
<a
name=
"1"
></a>
...
...
@@ -103,7 +107,7 @@ opencv3/
#### 1.2.1 直接下载安装
*
[
Paddle预测库官网
](
https://paddle
-
inference.
readthedocs.io/en/latest
/user_guides/download_lib.html
)
上提供了不同cuda版本的Linux预测库,可以在官网查看并选择合适的预测库版本(
*建议选择paddle版本>=2.0.1版本的预测库*
)。
*
[
Paddle预测库官网
](
https://paddleinference.
paddlepaddle.org.cn
/user_guides/download_lib.html
#linux
)
上提供了不同cuda版本的Linux预测库,可以在官网查看并选择合适的预测库版本(
*建议选择paddle版本>=2.0.1版本的预测库*
)。
*
下载之后使用下面的方法解压。
...
...
@@ -249,7 +253,7 @@ CUDNN_LIB_DIR=/your_cudnn_lib_dir
|gpu_id|int|0|GPU id,使用GPU时有效|
|gpu_mem|int|4000|申请的GPU内存|
|cpu_math_library_num_threads|int|10|CPU预测时的线程数,在机器核数充足的情况下,该值越大,预测速度越快|
|
us
e_mkldnn|bool|true|是否使用mkldnn库|
|
enabl
e_mkldnn|bool|true|是否使用mkldnn库|
-
检测模型相关
...
...
Prev
1
2
3
4
5
6
…
9
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