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
03bb378f
"vscode:/vscode.git/clone" did not exist on "e9eefe62f85cab38d51c5003e8d9b86575f360c0"
Commit
03bb378f
authored
Nov 25, 2021
by
LDOUBLEV
Browse files
fix TRT8 core bug
parents
a2a12fe4
2e9abcb9
Changes
207
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
544 additions
and
178 deletions
+544
-178
benchmark/run_det.sh
benchmark/run_det.sh
+11
-6
configs/det/ch_PP-OCRv2/ch_PP-OCRv2_det_cml.yml
configs/det/ch_PP-OCRv2/ch_PP-OCRv2_det_cml.yml
+0
-0
configs/det/ch_PP-OCRv2/ch_PP-OCRv2_det_distill.yml
configs/det/ch_PP-OCRv2/ch_PP-OCRv2_det_distill.yml
+1
-1
configs/det/ch_PP-OCRv2/ch_PP-OCRv2_det_dml.yml
configs/det/ch_PP-OCRv2/ch_PP-OCRv2_det_dml.yml
+0
-0
configs/det/ch_PP-OCRv2/ch_PP-OCRv2_det_student.yml
configs/det/ch_PP-OCRv2/ch_PP-OCRv2_det_student.yml
+0
-0
configs/det/det_r50_vd_sast_icdar15.yml
configs/det/det_r50_vd_sast_icdar15.yml
+2
-2
configs/det/det_r50_vd_sast_totaltext.yml
configs/det/det_r50_vd_sast_totaltext.yml
+1
-1
configs/rec/ch_PP-OCRv2/ch_PP-OCRv2_rec_enhanced_ctc_loss.yml
...igs/rec/ch_PP-OCRv2/ch_PP-OCRv2_rec_enhanced_ctc_loss.yml
+1
-2
configs/table/table_mv3.yml
configs/table/table_mv3.yml
+9
-8
deploy/cpp_infer/include/ocr_rec.h
deploy/cpp_infer/include/ocr_rec.h
+7
-3
deploy/cpp_infer/include/preprocess_op.h
deploy/cpp_infer/include/preprocess_op.h
+5
-0
deploy/cpp_infer/include/utility.h
deploy/cpp_infer/include/utility.h
+3
-0
deploy/cpp_infer/readme.md
deploy/cpp_infer/readme.md
+18
-12
deploy/cpp_infer/readme_en.md
deploy/cpp_infer/readme_en.md
+3
-3
deploy/cpp_infer/src/main.cpp
deploy/cpp_infer/src/main.cpp
+26
-23
deploy/cpp_infer/src/ocr_rec.cpp
deploy/cpp_infer/src/ocr_rec.cpp
+98
-73
deploy/cpp_infer/src/preprocess_op.cpp
deploy/cpp_infer/src/preprocess_op.cpp
+14
-2
deploy/cpp_infer/src/utility.cpp
deploy/cpp_infer/src/utility.cpp
+13
-0
deploy/cpp_infer/tools/build_opencv.sh
deploy/cpp_infer/tools/build_opencv.sh
+28
-0
deploy/lite/ocr_db_crnn.cc
deploy/lite/ocr_db_crnn.cc
+304
-42
No files found.
benchmark/run_det.sh
View file @
03bb378f
#!/bin/bash
# 提供可稳定复现性能的脚本,默认在标准docker环境内py37执行: paddlepaddle/paddle:latest-gpu-cuda10.1-cudnn7 paddle=2.1.2 py=37
# 执行目录: ./PaddleOCR
# 1 安装该模型需要的依赖 (如需开启优化策略请注明)
python
3.7
-m
pip
install
-r
requirements.txt
python
-m
pip
install
-r
requirements.txt
# 2 拷贝该模型需要数据、预训练模型
wget
-c
-p
./tain_data/ https://paddleocr.bj.bcebos.com/dygraph_v2.0/test/icdar2015.tar
&&
cd
train_data
&&
tar
xf icdar2015.tar
&&
cd
../
wget
-c
-p
./pretrain_models/ https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ResNet50_vd_pretrained.pdparams
wget
-P
./train_data/ https://paddleocr.bj.bcebos.com/dygraph_v2.0/test/icdar2015.tar
&&
cd
train_data
&&
tar
xf icdar2015.tar
&&
cd
../
wget
-P
./pretrain_models/ https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ResNet50_vd_pretrained.pdparams
wget
-P
./pretrain_models/ https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ResNet18_vd_pretrained.pdparams
wget
-P
./pretrain_models/ https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ResNet50_vd_ssld_pretrained.pdparams
# 3 批量运行(如不方便批量,1,2需放到单个模型中)
model_mode_list
=(
det_res18_db_v2.0 det_r50_vd_east
)
model_mode_list
=(
det_res18_db_v2.0 det_r50_vd_east
det_r50_vd_pse
)
fp_item_list
=(
fp32
)
bs_list
=(
8 16
)
for
model_mode
in
${
model_mode_list
[@]
}
;
do
...
...
@@ -15,11 +18,13 @@ for model_mode in ${model_mode_list[@]}; do
for
bs_item
in
${
bs_list
[@]
}
;
do
echo
"index is speed, 1gpus, begin,
${
model_name
}
"
run_mode
=
sp
CUDA_VISIBLE_DEVICES
=
0 bash benchmark/run_benchmark_det.sh
${
run_mode
}
${
bs_item
}
${
fp_item
}
10
${
model_mode
}
# (5min)
log_name
=
ocr_
${
model_mode
}
_
${
run_mode
}
_bs
${
bs_item
}
_
${
fp_item
}
CUDA_VISIBLE_DEVICES
=
0 bash benchmark/run_benchmark_det.sh
${
run_mode
}
${
bs_item
}
${
fp_item
}
1
${
model_mode
}
|
tee
${
log_path
}
/
${
log_name
}
_speed_1gpus 2>&1
# (5min)
sleep
60
echo
"index is speed, 8gpus, run_mode is multi_process, begin,
${
model_name
}
"
run_mode
=
mp
CUDA_VISIBLE_DEVICES
=
0,1,2,3,4,5,6,7 bash benchmark/run_benchmark_det.sh
${
run_mode
}
${
bs_item
}
${
fp_item
}
10
${
model_mode
}
log_name
=
ocr_
${
model_mode
}
_
${
run_mode
}
_bs
${
bs_item
}
_
${
fp_item
}
CUDA_VISIBLE_DEVICES
=
0,1,2,3,4,5,6,7 bash benchmark/run_benchmark_det.sh
${
run_mode
}
${
bs_item
}
${
fp_item
}
2
${
model_mode
}
|
tee
${
log_path
}
/
${
log_name
}
_speed_8gpus8p 2>&1
sleep
60
done
done
...
...
configs/det/ch_PP-OCRv2/ch_PP-OCR_det_cml.yml
→
configs/det/ch_PP-OCRv2/ch_PP-OCR
v2
_det_cml.yml
View file @
03bb378f
File moved
configs/det/ch_PP-OCRv2/ch_PP-OCR_det_distill.yml
→
configs/det/ch_PP-OCRv2/ch_PP-OCR
v2
_det_distill.yml
View file @
03bb378f
...
...
@@ -90,7 +90,7 @@ Optimizer:
PostProcess
:
name
:
DistillationDBPostProcess
model_name
:
[
"
Student"
,
"
Student2"
]
model_name
:
[
"
Student"
]
key
:
head_out
thresh
:
0.3
box_thresh
:
0.6
...
...
configs/det/ch_PP-OCRv2/ch_PP-OCR_det_dml.yml
→
configs/det/ch_PP-OCRv2/ch_PP-OCR
v2
_det_dml.yml
View file @
03bb378f
File moved
configs/det/ch_PP-OCRv2/ch_PP-OCR_det_student.yml
→
configs/det/ch_PP-OCRv2/ch_PP-OCR
v2
_det_student.yml
View file @
03bb378f
File moved
configs/det/det_r50_vd_sast_icdar15.yml
View file @
03bb378f
...
...
@@ -8,7 +8,7 @@ Global:
# evaluation is run every 5000 iterations after the 4000th iteration
eval_batch_step
:
[
4000
,
5000
]
cal_metric_during_train
:
False
pretrained_model
:
./pretrain_models/ResNet50_vd_ssld_pretrained
/
pretrained_model
:
./pretrain_models/ResNet50_vd_ssld_pretrained
checkpoints
:
save_inference_dir
:
use_visualdl
:
False
...
...
@@ -106,4 +106,4 @@ Eval:
shuffle
:
False
drop_last
:
False
batch_size_per_card
:
1
# must be 1
num_workers
:
2
\ No newline at end of file
num_workers
:
2
configs/det/det_r50_vd_sast_totaltext.yml
View file @
03bb378f
...
...
@@ -8,7 +8,7 @@ Global:
# evaluation is run every 5000 iterations after the 4000th iteration
eval_batch_step
:
[
4000
,
5000
]
cal_metric_during_train
:
False
pretrained_model
:
./pretrain_models/ResNet50_vd_ssld_pretrained
/
pretrained_model
:
./pretrain_models/ResNet50_vd_ssld_pretrained
checkpoints
:
save_inference_dir
:
use_visualdl
:
False
...
...
configs/rec/ch_PP-OCRv2/ch_PP-OCRv2_rec_enhanced_ctc_loss.yml
View file @
03bb378f
...
...
@@ -62,8 +62,7 @@ Loss:
weight
:
0.05
num_classes
:
6625
feat_dim
:
96
init_center
:
false
center_file_path
:
"
./train_center.pkl"
center_file_path
:
# you can also try to add ace loss on your own dataset
# - ACELoss:
# weight: 0.1
...
...
configs/table/table_mv3.yml
View file @
03bb378f
Global
:
use_gpu
:
true
epoch_num
:
5
0
epoch_num
:
40
0
log_smooth_window
:
20
print_batch_step
:
5
save_model_dir
:
./output/table_mv3/
save_epoch_step
:
5
save_epoch_step
:
3
# evaluation is run every 400 iterations after the 0th iteration
eval_batch_step
:
[
0
,
400
]
cal_metric_during_train
:
True
pretrained_model
:
pretrained_model
:
checkpoints
:
save_inference_dir
:
use_visualdl
:
False
infer_img
:
doc/
imgs_words/ch/word_1
.jpg
infer_img
:
doc/
table/table
.jpg
# for data or label process
character_dict_path
:
ppocr/utils/dict/table_structure_dict.txt
character_type
:
en
max_text_length
:
100
max_elem_length
:
5
00
max_elem_length
:
8
00
max_cell_num
:
500
infer_mode
:
False
process_total_num
:
0
process_cut_num
:
0
Optimizer
:
name
:
Adam
beta1
:
0.9
...
...
@@ -41,13 +40,15 @@ Architecture:
Backbone
:
name
:
MobileNetV3
scale
:
1.0
model_name
:
small
disable_se
:
True
model_name
:
large
Head
:
name
:
TableAttentionHead
hidden_size
:
256
l2_decay
:
0.00001
loc_type
:
2
max_text_length
:
100
max_elem_length
:
800
max_cell_num
:
500
Loss
:
name
:
TableAttentionLoss
...
...
deploy/cpp_infer/include/ocr_rec.h
View file @
03bb378f
...
...
@@ -44,7 +44,8 @@ public:
const
int
&
gpu_id
,
const
int
&
gpu_mem
,
const
int
&
cpu_math_library_num_threads
,
const
bool
&
use_mkldnn
,
const
string
&
label_path
,
const
bool
&
use_tensorrt
,
const
std
::
string
&
precision
)
{
const
bool
&
use_tensorrt
,
const
std
::
string
&
precision
,
const
int
&
rec_batch_num
)
{
this
->
use_gpu_
=
use_gpu
;
this
->
gpu_id_
=
gpu_id
;
this
->
gpu_mem_
=
gpu_mem
;
...
...
@@ -52,6 +53,7 @@ public:
this
->
use_mkldnn_
=
use_mkldnn
;
this
->
use_tensorrt_
=
use_tensorrt
;
this
->
precision_
=
precision
;
this
->
rec_batch_num_
=
rec_batch_num
;
this
->
label_list_
=
Utility
::
ReadDict
(
label_path
);
this
->
label_list_
.
insert
(
this
->
label_list_
.
begin
(),
...
...
@@ -64,7 +66,7 @@ public:
// Load Paddle inference model
void
LoadModel
(
const
std
::
string
&
model_dir
);
void
Run
(
cv
::
Mat
&
img
,
std
::
vector
<
double
>
*
times
);
void
Run
(
std
::
vector
<
cv
::
Mat
>
img
_list
,
std
::
vector
<
double
>
*
times
);
private:
std
::
shared_ptr
<
Predictor
>
predictor_
;
...
...
@@ -82,10 +84,12 @@ private:
bool
is_scale_
=
true
;
bool
use_tensorrt_
=
false
;
std
::
string
precision_
=
"fp32"
;
int
rec_batch_num_
=
6
;
// pre-process
CrnnResizeImg
resize_op_
;
Normalize
normalize_op_
;
Permute
permute_op_
;
Permute
Batch
permute_op_
;
// post-process
PostProcessor
post_processor_
;
...
...
deploy/cpp_infer/include/preprocess_op.h
View file @
03bb378f
...
...
@@ -44,6 +44,11 @@ public:
virtual
void
Run
(
const
cv
::
Mat
*
im
,
float
*
data
);
};
class
PermuteBatch
{
public:
virtual
void
Run
(
const
std
::
vector
<
cv
::
Mat
>
imgs
,
float
*
data
);
};
class
ResizeImgType0
{
public:
virtual
void
Run
(
const
cv
::
Mat
&
img
,
cv
::
Mat
&
resize_img
,
int
max_size_len
,
...
...
deploy/cpp_infer/include/utility.h
View file @
03bb378f
...
...
@@ -50,6 +50,9 @@ public:
static
cv
::
Mat
GetRotateCropImage
(
const
cv
::
Mat
&
srcimage
,
std
::
vector
<
std
::
vector
<
int
>>
box
);
static
std
::
vector
<
int
>
argsort
(
const
std
::
vector
<
float
>&
array
);
};
}
// namespace PaddleOCR
\ No newline at end of file
deploy/cpp_infer/readme.md
View file @
03bb378f
...
...
@@ -34,10 +34,10 @@ PaddleOCR模型部署。
*
首先需要从opencv官网上下载在Linux环境下源码编译的包,以opencv3.4.7为例,下载命令如下。
```
```
bash
cd
deploy/cpp_infer
wget https://
github.com
/opencv/opencv
/archive/
3.4.7.tar.gz
tar -xf 3.4.7.tar.gz
wget https://
paddleocr.bj.bcebos.com/libs
/opencv/opencv
-
3.4.7.tar.gz
tar
-xf
opencv-
3.4.7.tar.gz
```
最终可以在当前目录下看到
`opencv-3.4.7/`
的文件夹。
...
...
@@ -45,12 +45,13 @@ tar -xf 3.4.7.tar.gz
*
编译opencv,设置opencv源码路径(
`root_path`
)以及安装路径(
`install_path`
)。进入opencv源码路径下,按照下面的方式进行编译。
```
shell
root_path
=
your_opencv_root_path
root_path
=
"
your_opencv_root_path
"
install_path
=
${
root_path
}
/opencv3
build_dir
=
${
root_path
}
/build
rm
-rf
build
mkdir
build
cd
build
rm
-rf
${
build
_dir
}
mkdir
${
build
_dir
}
cd
${
build
_dir
}
cmake ..
\
-DCMAKE_INSTALL_PREFIX
=
${
install_path
}
\
...
...
@@ -74,6 +75,11 @@ make -j
make
install
```
也可以直接修改
`tools/build_opencv.sh`
的内容,然后直接运行下面的命令进行编译。
```
shell
sh tools/build_opencv.sh
```
其中
`root_path`
为下载的opencv源码路径,
`install_path`
为opencv的安装路径,
`make install`
完成之后,会在该文件夹下生成opencv头文件和库文件,用于后面的OCR代码编译。
...
...
@@ -233,12 +239,12 @@ CUDNN_LIB_DIR=/your_cudnn_lib_dir
--image_dir
=
../../doc/imgs/12.jpg
```
更多
参数
如下:
更多
支持的可调节参数解释
如下:
-
通用参数
|参数名称|类型|默认参数|意义|
| --- | --- | --- | --- |
|
:
---
:
|
:
---
:
|
:
---
:
|
:
---
:
|
|use_gpu|bool|false|是否使用GPU|
|gpu_id|int|0|GPU id,使用GPU时有效|
|gpu_mem|int|4000|申请的GPU内存|
...
...
@@ -248,7 +254,7 @@ CUDNN_LIB_DIR=/your_cudnn_lib_dir
-
检测模型相关
|参数名称|类型|默认参数|意义|
| --- | --- | --- | --- |
|
:
---
:
|
:
---
:
|
:
---
:
|
:
---
:
|
|det_model_dir|string|-|检测模型inference model地址|
|max_side_len|int|960|输入图像长宽大于960时,等比例缩放图像,使得图像最长边为960|
|det_db_thresh|float|0.3|用于过滤DB预测的二值化图像,设置为0.-0.3对结果影响不明显|
...
...
@@ -260,7 +266,7 @@ CUDNN_LIB_DIR=/your_cudnn_lib_dir
-
方向分类器相关
|参数名称|类型|默认参数|意义|
| --- | --- | --- | --- |
|
:
---
:
|
:
---
:
|
:
---
:
|
:
---
:
|
|use_angle_cls|bool|false|是否使用方向分类器|
|cls_model_dir|string|-|方向分类器inference model地址|
|cls_thresh|float|0.9|方向分类器的得分阈值|
...
...
@@ -268,7 +274,7 @@ CUDNN_LIB_DIR=/your_cudnn_lib_dir
-
识别模型相关
|参数名称|类型|默认参数|意义|
| --- | --- | --- | --- |
|
:
---
:
|
:
---
:
|
:
---
:
|
:
---
:
|
|rec_model_dir|string|-|识别模型inference model地址|
|char_list_file|string|../../ppocr/utils/ppocr_keys_v1.txt|字典文件|
...
...
deploy/cpp_infer/readme_en.md
View file @
03bb378f
...
...
@@ -17,10 +17,10 @@ PaddleOCR model deployment.
*
First of all, you need to download the source code compiled package in the Linux environment from the opencv official website. Taking opencv3.4.7 as an example, the download command is as follows.
```
```
bash
cd
deploy/cpp_infer
wget https://
github.com
/opencv/opencv
/archive/
3.4.7.tar.gz
tar -xf 3.4.7.tar.gz
wget https://
paddleocr.bj.bcebos.com/libs
/opencv/opencv
-
3.4.7.tar.gz
tar
-xf
opencv-
3.4.7.tar.gz
```
Finally, you can see the folder of
`opencv-3.4.7/`
in the current directory.
...
...
deploy/cpp_infer/src/main.cpp
View file @
03bb378f
...
...
@@ -61,7 +61,7 @@ DEFINE_string(cls_model_dir, "", "Path of cls inference model.");
DEFINE_double
(
cls_thresh
,
0.9
,
"Threshold of cls_thresh."
);
// recognition related
DEFINE_string
(
rec_model_dir
,
""
,
"Path of rec inference model."
);
DEFINE_int32
(
rec_batch_num
,
1
,
"rec_batch_num."
);
DEFINE_int32
(
rec_batch_num
,
6
,
"rec_batch_num."
);
DEFINE_string
(
char_list_file
,
"../../ppocr/utils/ppocr_keys_v1.txt"
,
"Path of dictionary."
);
...
...
@@ -146,8 +146,9 @@ int main_rec(std::vector<cv::String> cv_all_img_names) {
CRNNRecognizer
rec
(
FLAGS_rec_model_dir
,
FLAGS_use_gpu
,
FLAGS_gpu_id
,
FLAGS_gpu_mem
,
FLAGS_cpu_threads
,
FLAGS_enable_mkldnn
,
char_list_file
,
FLAGS_use_tensorrt
,
FLAGS_precision
);
FLAGS_use_tensorrt
,
FLAGS_precision
,
FLAGS_rec_batch_num
);
std
::
vector
<
cv
::
Mat
>
img_list
;
for
(
int
i
=
0
;
i
<
cv_all_img_names
.
size
();
++
i
)
{
LOG
(
INFO
)
<<
"The predict img: "
<<
cv_all_img_names
[
i
];
...
...
@@ -156,22 +157,21 @@ int main_rec(std::vector<cv::String> cv_all_img_names) {
std
::
cerr
<<
"[ERROR] image read failed! image path: "
<<
cv_all_img_names
[
i
]
<<
endl
;
exit
(
1
);
}
std
::
vector
<
double
>
rec_times
;
rec
.
Run
(
srcimg
,
&
rec_times
);
time_info
[
0
]
+=
rec_times
[
0
];
time_info
[
1
]
+=
rec_times
[
1
];
time_info
[
2
]
+=
rec_times
[
2
];
img_list
.
push_back
(
srcimg
);
}
std
::
vector
<
double
>
rec_times
;
rec
.
Run
(
img_list
,
&
rec_times
);
time_info
[
0
]
+=
rec_times
[
0
];
time_info
[
1
]
+=
rec_times
[
1
];
time_info
[
2
]
+=
rec_times
[
2
];
if
(
FLAGS_benchmark
)
{
AutoLogger
autolog
(
"ocr_rec"
,
FLAGS_use_gpu
,
FLAGS_use_tensorrt
,
FLAGS_enable_mkldnn
,
FLAGS_cpu_threads
,
1
,
FLAGS_rec_batch_num
,
"dynamic"
,
FLAGS_precision
,
time_info
,
...
...
@@ -209,7 +209,7 @@ int main_system(std::vector<cv::String> cv_all_img_names) {
CRNNRecognizer
rec
(
FLAGS_rec_model_dir
,
FLAGS_use_gpu
,
FLAGS_gpu_id
,
FLAGS_gpu_mem
,
FLAGS_cpu_threads
,
FLAGS_enable_mkldnn
,
char_list_file
,
FLAGS_use_tensorrt
,
FLAGS_precision
);
FLAGS_use_tensorrt
,
FLAGS_precision
,
FLAGS_rec_batch_num
);
for
(
int
i
=
0
;
i
<
cv_all_img_names
.
size
();
++
i
)
{
LOG
(
INFO
)
<<
"The predict img: "
<<
cv_all_img_names
[
i
];
...
...
@@ -228,19 +228,22 @@ int main_system(std::vector<cv::String> cv_all_img_names) {
time_info_det
[
1
]
+=
det_times
[
1
];
time_info_det
[
2
]
+=
det_times
[
2
];
cv
::
Mat
crop_img
;
std
::
vector
<
cv
::
Mat
>
img_list
;
for
(
int
j
=
0
;
j
<
boxes
.
size
();
j
++
)
{
crop_img
=
Utility
::
GetRotateCropImage
(
srcimg
,
boxes
[
j
]);
if
(
cls
!=
nullptr
)
{
crop_img
=
cls
->
Run
(
crop_img
);
}
rec
.
Run
(
crop_img
,
&
rec_times
);
time_info_rec
[
0
]
+=
rec_times
[
0
];
time_info_rec
[
1
]
+=
rec_times
[
1
];
time_info_rec
[
2
]
+=
rec_times
[
2
];
cv
::
Mat
crop_img
;
crop_img
=
Utility
::
GetRotateCropImage
(
srcimg
,
boxes
[
j
]);
if
(
cls
!=
nullptr
)
{
crop_img
=
cls
->
Run
(
crop_img
);
}
img_list
.
push_back
(
crop_img
);
}
rec
.
Run
(
img_list
,
&
rec_times
);
time_info_rec
[
0
]
+=
rec_times
[
0
];
time_info_rec
[
1
]
+=
rec_times
[
1
];
time_info_rec
[
2
]
+=
rec_times
[
2
];
}
if
(
FLAGS_benchmark
)
{
AutoLogger
autolog_det
(
"ocr_det"
,
FLAGS_use_gpu
,
...
...
@@ -257,7 +260,7 @@ int main_system(std::vector<cv::String> cv_all_img_names) {
FLAGS_use_tensorrt
,
FLAGS_enable_mkldnn
,
FLAGS_cpu_threads
,
1
,
FLAGS_rec_batch_num
,
"dynamic"
,
FLAGS_precision
,
time_info_rec
,
...
...
deploy/cpp_infer/src/ocr_rec.cpp
View file @
03bb378f
...
...
@@ -15,83 +15,108 @@
#include <include/ocr_rec.h>
namespace
PaddleOCR
{
void
CRNNRecognizer
::
Run
(
cv
::
Mat
&
img
,
std
::
vector
<
double
>
*
times
)
{
cv
::
Mat
srcimg
;
img
.
copyTo
(
srcimg
);
cv
::
Mat
resize_img
;
float
wh_ratio
=
float
(
srcimg
.
cols
)
/
float
(
srcimg
.
rows
);
auto
preprocess_start
=
std
::
chrono
::
steady_clock
::
now
();
this
->
resize_op_
.
Run
(
srcimg
,
resize_img
,
wh_ratio
,
this
->
use_tensorrt_
);
this
->
normalize_op_
.
Run
(
&
resize_img
,
this
->
mean_
,
this
->
scale_
,
this
->
is_scale_
);
std
::
vector
<
float
>
input
(
1
*
3
*
resize_img
.
rows
*
resize_img
.
cols
,
0.0
f
);
this
->
permute_op_
.
Run
(
&
resize_img
,
input
.
data
());
auto
preprocess_end
=
std
::
chrono
::
steady_clock
::
now
();
// Inference.
auto
input_names
=
this
->
predictor_
->
GetInputNames
();
auto
input_t
=
this
->
predictor_
->
GetInputHandle
(
input_names
[
0
]);
input_t
->
Reshape
({
1
,
3
,
resize_img
.
rows
,
resize_img
.
cols
});
auto
inference_start
=
std
::
chrono
::
steady_clock
::
now
();
input_t
->
CopyFromCpu
(
input
.
data
());
this
->
predictor_
->
Run
();
std
::
vector
<
float
>
predict_batch
;
auto
output_names
=
this
->
predictor_
->
GetOutputNames
();
auto
output_t
=
this
->
predictor_
->
GetOutputHandle
(
output_names
[
0
]);
auto
predict_shape
=
output_t
->
shape
();
int
out_num
=
std
::
accumulate
(
predict_shape
.
begin
(),
predict_shape
.
end
(),
1
,
void
CRNNRecognizer
::
Run
(
std
::
vector
<
cv
::
Mat
>
img_list
,
std
::
vector
<
double
>
*
times
)
{
std
::
chrono
::
duration
<
float
>
preprocess_diff
=
std
::
chrono
::
steady_clock
::
now
()
-
std
::
chrono
::
steady_clock
::
now
();
std
::
chrono
::
duration
<
float
>
inference_diff
=
std
::
chrono
::
steady_clock
::
now
()
-
std
::
chrono
::
steady_clock
::
now
();
std
::
chrono
::
duration
<
float
>
postprocess_diff
=
std
::
chrono
::
steady_clock
::
now
()
-
std
::
chrono
::
steady_clock
::
now
();
int
img_num
=
img_list
.
size
();
std
::
vector
<
float
>
width_list
;
for
(
int
i
=
0
;
i
<
img_num
;
i
++
)
{
width_list
.
push_back
(
float
(
img_list
[
i
].
cols
)
/
img_list
[
i
].
rows
);
}
std
::
vector
<
int
>
indices
=
Utility
::
argsort
(
width_list
);
for
(
int
beg_img_no
=
0
;
beg_img_no
<
img_num
;
beg_img_no
+=
this
->
rec_batch_num_
)
{
auto
preprocess_start
=
std
::
chrono
::
steady_clock
::
now
();
int
end_img_no
=
min
(
img_num
,
beg_img_no
+
this
->
rec_batch_num_
);
float
max_wh_ratio
=
0
;
for
(
int
ino
=
beg_img_no
;
ino
<
end_img_no
;
ino
++
)
{
int
h
=
img_list
[
indices
[
ino
]].
rows
;
int
w
=
img_list
[
indices
[
ino
]].
cols
;
float
wh_ratio
=
w
*
1.0
/
h
;
max_wh_ratio
=
max
(
max_wh_ratio
,
wh_ratio
);
}
std
::
vector
<
cv
::
Mat
>
norm_img_batch
;
for
(
int
ino
=
beg_img_no
;
ino
<
end_img_no
;
ino
++
)
{
cv
::
Mat
srcimg
;
img_list
[
indices
[
ino
]].
copyTo
(
srcimg
);
cv
::
Mat
resize_img
;
this
->
resize_op_
.
Run
(
srcimg
,
resize_img
,
max_wh_ratio
,
this
->
use_tensorrt_
);
this
->
normalize_op_
.
Run
(
&
resize_img
,
this
->
mean_
,
this
->
scale_
,
this
->
is_scale_
);
norm_img_batch
.
push_back
(
resize_img
);
}
int
batch_width
=
int
(
ceilf
(
32
*
max_wh_ratio
))
-
1
;
std
::
vector
<
float
>
input
(
this
->
rec_batch_num_
*
3
*
32
*
batch_width
,
0.0
f
);
this
->
permute_op_
.
Run
(
norm_img_batch
,
input
.
data
());
auto
preprocess_end
=
std
::
chrono
::
steady_clock
::
now
();
preprocess_diff
+=
preprocess_end
-
preprocess_start
;
// Inference.
auto
input_names
=
this
->
predictor_
->
GetInputNames
();
auto
input_t
=
this
->
predictor_
->
GetInputHandle
(
input_names
[
0
]);
input_t
->
Reshape
({
this
->
rec_batch_num_
,
3
,
32
,
batch_width
});
auto
inference_start
=
std
::
chrono
::
steady_clock
::
now
();
input_t
->
CopyFromCpu
(
input
.
data
());
this
->
predictor_
->
Run
();
std
::
vector
<
float
>
predict_batch
;
auto
output_names
=
this
->
predictor_
->
GetOutputNames
();
auto
output_t
=
this
->
predictor_
->
GetOutputHandle
(
output_names
[
0
]);
auto
predict_shape
=
output_t
->
shape
();
int
out_num
=
std
::
accumulate
(
predict_shape
.
begin
(),
predict_shape
.
end
(),
1
,
std
::
multiplies
<
int
>
());
predict_batch
.
resize
(
out_num
);
output_t
->
CopyToCpu
(
predict_batch
.
data
());
auto
inference_end
=
std
::
chrono
::
steady_clock
::
now
();
// ctc decode
auto
postprocess_start
=
std
::
chrono
::
steady_clock
::
now
();
std
::
vector
<
std
::
string
>
str_res
;
int
argmax_idx
;
int
last_index
=
0
;
float
score
=
0.
f
;
int
count
=
0
;
float
max_value
=
0.0
f
;
for
(
int
n
=
0
;
n
<
predict_shape
[
1
];
n
++
)
{
argmax_idx
=
int
(
Utility
::
argmax
(
&
predict_batch
[
n
*
predict_shape
[
2
]],
&
predict_batch
[(
n
+
1
)
*
predict_shape
[
2
]]));
max_value
=
float
(
*
std
::
max_element
(
&
predict_batch
[
n
*
predict_shape
[
2
]],
&
predict_batch
[(
n
+
1
)
*
predict_shape
[
2
]]));
if
(
argmax_idx
>
0
&&
(
!
(
n
>
0
&&
argmax_idx
==
last_index
)))
{
score
+=
max_value
;
count
+=
1
;
str_res
.
push_back
(
label_list_
[
argmax_idx
]);
predict_batch
.
resize
(
out_num
);
output_t
->
CopyToCpu
(
predict_batch
.
data
());
auto
inference_end
=
std
::
chrono
::
steady_clock
::
now
();
inference_diff
+=
inference_end
-
inference_start
;
// ctc decode
auto
postprocess_start
=
std
::
chrono
::
steady_clock
::
now
();
for
(
int
m
=
0
;
m
<
predict_shape
[
0
];
m
++
)
{
std
::
vector
<
std
::
string
>
str_res
;
int
argmax_idx
;
int
last_index
=
0
;
float
score
=
0.
f
;
int
count
=
0
;
float
max_value
=
0.0
f
;
for
(
int
n
=
0
;
n
<
predict_shape
[
1
];
n
++
)
{
argmax_idx
=
int
(
Utility
::
argmax
(
&
predict_batch
[(
m
*
predict_shape
[
1
]
+
n
)
*
predict_shape
[
2
]],
&
predict_batch
[(
m
*
predict_shape
[
1
]
+
n
+
1
)
*
predict_shape
[
2
]]));
max_value
=
float
(
*
std
::
max_element
(
&
predict_batch
[(
m
*
predict_shape
[
1
]
+
n
)
*
predict_shape
[
2
]],
&
predict_batch
[(
m
*
predict_shape
[
1
]
+
n
+
1
)
*
predict_shape
[
2
]]));
if
(
argmax_idx
>
0
&&
(
!
(
n
>
0
&&
argmax_idx
==
last_index
)))
{
score
+=
max_value
;
count
+=
1
;
str_res
.
push_back
(
label_list_
[
argmax_idx
]);
}
last_index
=
argmax_idx
;
}
score
/=
count
;
if
(
isnan
(
score
))
continue
;
for
(
int
i
=
0
;
i
<
str_res
.
size
();
i
++
)
{
std
::
cout
<<
str_res
[
i
];
}
std
::
cout
<<
"
\t
score: "
<<
score
<<
std
::
endl
;
}
auto
postprocess_end
=
std
::
chrono
::
steady_clock
::
now
();
postprocess_diff
+=
postprocess_end
-
postprocess_start
;
}
last_index
=
argmax_idx
;
}
auto
postprocess_end
=
std
::
chrono
::
steady_clock
::
now
();
score
/=
count
;
for
(
int
i
=
0
;
i
<
str_res
.
size
();
i
++
)
{
std
::
cout
<<
str_res
[
i
];
}
std
::
cout
<<
"
\t
score: "
<<
score
<<
std
::
endl
;
std
::
chrono
::
duration
<
float
>
preprocess_diff
=
preprocess_end
-
preprocess_start
;
times
->
push_back
(
double
(
preprocess_diff
.
count
()
*
1000
));
std
::
chrono
::
duration
<
float
>
inference_diff
=
inference_end
-
inference_start
;
times
->
push_back
(
double
(
inference_diff
.
count
()
*
1000
));
std
::
chrono
::
duration
<
float
>
postprocess_diff
=
postprocess_end
-
postprocess_start
;
times
->
push_back
(
double
(
postprocess_diff
.
count
()
*
1000
));
times
->
push_back
(
double
(
preprocess_diff
.
count
()
*
1000
));
times
->
push_back
(
double
(
inference_diff
.
count
()
*
1000
));
times
->
push_back
(
double
(
postprocess_diff
.
count
()
*
1000
));
}
void
CRNNRecognizer
::
LoadModel
(
const
std
::
string
&
model_dir
)
{
// AnalysisConfig config;
paddle_infer
::
Config
config
;
...
...
deploy/cpp_infer/src/preprocess_op.cpp
View file @
03bb378f
...
...
@@ -40,6 +40,17 @@ void Permute::Run(const cv::Mat *im, float *data) {
}
}
void
PermuteBatch
::
Run
(
const
std
::
vector
<
cv
::
Mat
>
imgs
,
float
*
data
)
{
for
(
int
j
=
0
;
j
<
imgs
.
size
();
j
++
){
int
rh
=
imgs
[
j
].
rows
;
int
rw
=
imgs
[
j
].
cols
;
int
rc
=
imgs
[
j
].
channels
();
for
(
int
i
=
0
;
i
<
rc
;
++
i
)
{
cv
::
extractChannel
(
imgs
[
j
],
cv
::
Mat
(
rh
,
rw
,
CV_32FC1
,
data
+
(
j
*
rc
+
i
)
*
rh
*
rw
),
i
);
}
}
}
void
Normalize
::
Run
(
cv
::
Mat
*
im
,
const
std
::
vector
<
float
>
&
mean
,
const
std
::
vector
<
float
>
&
scale
,
const
bool
is_scale
)
{
double
e
=
1.0
;
...
...
@@ -90,16 +101,17 @@ void CrnnResizeImg::Run(const cv::Mat &img, cv::Mat &resize_img, float wh_ratio,
imgC
=
rec_image_shape
[
0
];
imgH
=
rec_image_shape
[
1
];
imgW
=
rec_image_shape
[
2
];
imgW
=
int
(
32
*
wh_ratio
);
float
ratio
=
float
(
img
.
cols
)
/
float
(
img
.
rows
);
int
resize_w
,
resize_h
;
if
(
ceilf
(
imgH
*
ratio
)
>
imgW
)
resize_w
=
imgW
;
else
resize_w
=
int
(
ceilf
(
imgH
*
ratio
));
cv
::
resize
(
img
,
resize_img
,
cv
::
Size
(
resize_w
,
imgH
),
0.
f
,
0.
f
,
cv
::
INTER_LINEAR
);
cv
::
copyMakeBorder
(
resize_img
,
resize_img
,
0
,
0
,
0
,
...
...
deploy/cpp_infer/src/utility.cpp
View file @
03bb378f
...
...
@@ -147,4 +147,17 @@ cv::Mat Utility::GetRotateCropImage(const cv::Mat &srcimage,
}
}
std
::
vector
<
int
>
Utility
::
argsort
(
const
std
::
vector
<
float
>&
array
)
{
const
int
array_len
(
array
.
size
());
std
::
vector
<
int
>
array_index
(
array_len
,
0
);
for
(
int
i
=
0
;
i
<
array_len
;
++
i
)
array_index
[
i
]
=
i
;
std
::
sort
(
array_index
.
begin
(),
array_index
.
end
(),
[
&
array
](
int
pos1
,
int
pos2
)
{
return
(
array
[
pos1
]
<
array
[
pos2
]);
});
return
array_index
;
}
}
// namespace PaddleOCR
\ No newline at end of file
deploy/cpp_infer/tools/build_opencv.sh
0 → 100644
View file @
03bb378f
root_path
=
"/paddle/PaddleOCR/deploy/cpp_infer/opencv-3.4.7"
install_path
=
${
root_path
}
/opencv3
build_dir
=
${
root_path
}
/build
rm
-rf
${
build_dir
}
mkdir
${
build_dir
}
cd
${
build_dir
}
cmake ..
\
-DCMAKE_INSTALL_PREFIX
=
${
install_path
}
\
-DCMAKE_BUILD_TYPE
=
Release
\
-DBUILD_SHARED_LIBS
=
OFF
\
-DWITH_IPP
=
OFF
\
-DBUILD_IPP_IW
=
OFF
\
-DWITH_LAPACK
=
OFF
\
-DWITH_EIGEN
=
OFF
\
-DCMAKE_INSTALL_LIBDIR
=
lib64
\
-DWITH_ZLIB
=
ON
\
-DBUILD_ZLIB
=
ON
\
-DWITH_JPEG
=
ON
\
-DBUILD_JPEG
=
ON
\
-DWITH_PNG
=
ON
\
-DBUILD_PNG
=
ON
\
-DWITH_TIFF
=
ON
\
-DBUILD_TIFF
=
ON
make
-j
make
install
deploy/lite/ocr_db_crnn.cc
View file @
03bb378f
...
...
@@ -12,12 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "paddle_api.h" // NOLINT
#include <chrono>
#include "paddle_api.h" // NOLINT
#include "paddle_place.h"
#include "cls_process.h"
#include "crnn_process.h"
#include "db_post_process.h"
#include "AutoLog/auto_log/lite_autolog.h"
using
namespace
paddle
::
lite_api
;
// NOLINT
using
namespace
std
;
...
...
@@ -27,7 +29,7 @@ void NeonMeanScale(const float *din, float *dout, int size,
const
std
::
vector
<
float
>
mean
,
const
std
::
vector
<
float
>
scale
)
{
if
(
mean
.
size
()
!=
3
||
scale
.
size
()
!=
3
)
{
std
::
cerr
<<
"[ERROR] mean or scale size must equal to 3
\n
"
;
std
::
cerr
<<
"[ERROR] mean or scale size must equal to 3
"
<<
std
::
endl
;
exit
(
1
);
}
float32x4_t
vmean0
=
vdupq_n_f32
(
mean
[
0
]);
...
...
@@ -159,7 +161,8 @@ void RunRecModel(std::vector<std::vector<std::vector<int>>> boxes, cv::Mat img,
std
::
vector
<
float
>
&
rec_text_score
,
std
::
vector
<
std
::
string
>
charactor_dict
,
std
::
shared_ptr
<
PaddlePredictor
>
predictor_cls
,
int
use_direction_classify
)
{
int
use_direction_classify
,
std
::
vector
<
double
>
*
times
)
{
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
};
...
...
@@ -169,7 +172,10 @@ void RunRecModel(std::vector<std::vector<std::vector<int>>> boxes, cv::Mat img,
cv
::
Mat
resize_img
;
int
index
=
0
;
std
::
vector
<
double
>
time_info
=
{
0
,
0
,
0
};
for
(
int
i
=
boxes
.
size
()
-
1
;
i
>=
0
;
i
--
)
{
auto
preprocess_start
=
std
::
chrono
::
steady_clock
::
now
();
crop_img
=
GetRotateCropImage
(
srcimg
,
boxes
[
i
]);
if
(
use_direction_classify
>=
1
)
{
crop_img
=
RunClsModel
(
crop_img
,
predictor_cls
);
...
...
@@ -188,7 +194,9 @@ void RunRecModel(std::vector<std::vector<std::vector<int>>> boxes, cv::Mat img,
auto
*
data0
=
input_tensor0
->
mutable_data
<
float
>
();
NeonMeanScale
(
dimg
,
data0
,
resize_img
.
rows
*
resize_img
.
cols
,
mean
,
scale
);
auto
preprocess_end
=
std
::
chrono
::
steady_clock
::
now
();
//// Run CRNN predictor
auto
inference_start
=
std
::
chrono
::
steady_clock
::
now
();
predictor_crnn
->
Run
();
// Get output and run postprocess
...
...
@@ -196,8 +204,10 @@ void RunRecModel(std::vector<std::vector<std::vector<int>>> boxes, cv::Mat img,
std
::
move
(
predictor_crnn
->
GetOutput
(
0
)));
auto
*
predict_batch
=
output_tensor0
->
data
<
float
>
();
auto
predict_shape
=
output_tensor0
->
shape
();
auto
inference_end
=
std
::
chrono
::
steady_clock
::
now
();
// ctc decode
auto
postprocess_start
=
std
::
chrono
::
steady_clock
::
now
();
std
::
string
str_res
;
int
argmax_idx
;
int
last_index
=
0
;
...
...
@@ -221,19 +231,33 @@ void RunRecModel(std::vector<std::vector<std::vector<int>>> boxes, cv::Mat img,
score
/=
count
;
rec_text
.
push_back
(
str_res
);
rec_text_score
.
push_back
(
score
);
auto
postprocess_end
=
std
::
chrono
::
steady_clock
::
now
();
std
::
chrono
::
duration
<
float
>
preprocess_diff
=
preprocess_end
-
preprocess_start
;
time_info
[
0
]
+=
double
(
preprocess_diff
.
count
()
*
1000
);
std
::
chrono
::
duration
<
float
>
inference_diff
=
inference_end
-
inference_start
;
time_info
[
1
]
+=
double
(
inference_diff
.
count
()
*
1000
);
std
::
chrono
::
duration
<
float
>
postprocess_diff
=
postprocess_end
-
postprocess_start
;
time_info
[
2
]
+=
double
(
postprocess_diff
.
count
()
*
1000
);
}
times
->
push_back
(
time_info
[
0
]);
times
->
push_back
(
time_info
[
1
]);
times
->
push_back
(
time_info
[
2
]);
}
std
::
vector
<
std
::
vector
<
std
::
vector
<
int
>>>
RunDetModel
(
std
::
shared_ptr
<
PaddlePredictor
>
predictor
,
cv
::
Mat
img
,
std
::
map
<
std
::
string
,
double
>
Config
)
{
std
::
map
<
std
::
string
,
double
>
Config
,
std
::
vector
<
double
>
*
times
)
{
// Read img
int
max_side_len
=
int
(
Config
[
"max_side_len"
]);
int
det_db_use_dilate
=
int
(
Config
[
"det_db_use_dilate"
]);
cv
::
Mat
srcimg
;
img
.
copyTo
(
srcimg
);
auto
preprocess_start
=
std
::
chrono
::
steady_clock
::
now
();
std
::
vector
<
float
>
ratio_hw
;
img
=
DetResizeImg
(
img
,
max_side_len
,
ratio_hw
);
cv
::
Mat
img_fp
;
...
...
@@ -248,8 +272,10 @@ RunDetModel(std::shared_ptr<PaddlePredictor> predictor, cv::Mat img,
std
::
vector
<
float
>
scale
=
{
1
/
0.229
f
,
1
/
0.224
f
,
1
/
0.225
f
};
const
float
*
dimg
=
reinterpret_cast
<
const
float
*>
(
img_fp
.
data
);
NeonMeanScale
(
dimg
,
data0
,
img_fp
.
rows
*
img_fp
.
cols
,
mean
,
scale
);
auto
preprocess_end
=
std
::
chrono
::
steady_clock
::
now
();
// Run predictor
auto
inference_start
=
std
::
chrono
::
steady_clock
::
now
();
predictor
->
Run
();
// Get output and post process
...
...
@@ -257,8 +283,10 @@ RunDetModel(std::shared_ptr<PaddlePredictor> predictor, cv::Mat img,
std
::
move
(
predictor
->
GetOutput
(
0
)));
auto
*
outptr
=
output_tensor
->
data
<
float
>
();
auto
shape_out
=
output_tensor
->
shape
();
auto
inference_end
=
std
::
chrono
::
steady_clock
::
now
();
// Save output
auto
postprocess_start
=
std
::
chrono
::
steady_clock
::
now
();
float
pred
[
shape_out
[
2
]
*
shape_out
[
3
]];
unsigned
char
cbuf
[
shape_out
[
2
]
*
shape_out
[
3
]];
...
...
@@ -287,14 +315,23 @@ RunDetModel(std::shared_ptr<PaddlePredictor> predictor, cv::Mat img,
std
::
vector
<
std
::
vector
<
std
::
vector
<
int
>>>
filter_boxes
=
FilterTagDetRes
(
boxes
,
ratio_hw
[
0
],
ratio_hw
[
1
],
srcimg
);
auto
postprocess_end
=
std
::
chrono
::
steady_clock
::
now
();
std
::
chrono
::
duration
<
float
>
preprocess_diff
=
preprocess_end
-
preprocess_start
;
times
->
push_back
(
double
(
preprocess_diff
.
count
()
*
1000
));
std
::
chrono
::
duration
<
float
>
inference_diff
=
inference_end
-
inference_start
;
times
->
push_back
(
double
(
inference_diff
.
count
()
*
1000
));
std
::
chrono
::
duration
<
float
>
postprocess_diff
=
postprocess_end
-
postprocess_start
;
times
->
push_back
(
double
(
postprocess_diff
.
count
()
*
1000
));
return
filter_boxes
;
}
std
::
shared_ptr
<
PaddlePredictor
>
loadModel
(
std
::
string
model_file
)
{
std
::
shared_ptr
<
PaddlePredictor
>
loadModel
(
std
::
string
model_file
,
int
num_threads
)
{
MobileConfig
config
;
config
.
set_model_from_file
(
model_file
);
config
.
set_threads
(
num_threads
);
std
::
shared_ptr
<
PaddlePredictor
>
predictor
=
CreatePaddlePredictor
<
MobileConfig
>
(
config
);
return
predictor
;
...
...
@@ -354,60 +391,285 @@ std::map<std::string, double> LoadConfigTxt(std::string config_path) {
return
dict
;
}
int
main
(
int
argc
,
char
**
argv
)
{
if
(
argc
<
5
)
{
std
::
cerr
<<
"[ERROR] usage: "
<<
argv
[
0
]
<<
" det_model_file cls_model_file rec_model_file image_path "
"charactor_dict
\n
"
;
void
check_params
(
int
argc
,
char
**
argv
)
{
if
(
argc
<=
1
||
(
strcmp
(
argv
[
1
],
"det"
)
!=
0
&&
strcmp
(
argv
[
1
],
"rec"
)
!=
0
&&
strcmp
(
argv
[
1
],
"system"
)
!=
0
))
{
std
::
cerr
<<
"Please choose one mode of [det, rec, system] !"
<<
std
::
endl
;
exit
(
1
);
}
std
::
string
det_model_file
=
argv
[
1
];
std
::
string
rec_model_file
=
argv
[
2
];
std
::
string
cls_model_file
=
argv
[
3
];
std
::
string
img_path
=
argv
[
4
];
std
::
string
dict_path
=
argv
[
5
];
if
(
strcmp
(
argv
[
1
],
"det"
)
==
0
)
{
if
(
argc
<
9
){
std
::
cerr
<<
"[ERROR] usage:"
<<
argv
[
0
]
<<
" det det_model runtime_device num_threads batchsize img_dir det_config lite_benchmark_value"
<<
std
::
endl
;
exit
(
1
);
}
}
if
(
strcmp
(
argv
[
1
],
"rec"
)
==
0
)
{
if
(
argc
<
9
){
std
::
cerr
<<
"[ERROR] usage:"
<<
argv
[
0
]
<<
" rec rec_model runtime_device num_threads batchsize img_dir key_txt lite_benchmark_value"
<<
std
::
endl
;
exit
(
1
);
}
}
if
(
strcmp
(
argv
[
1
],
"system"
)
==
0
)
{
if
(
argc
<
12
){
std
::
cerr
<<
"[ERROR] usage:"
<<
argv
[
0
]
<<
" system det_model rec_model clas_model runtime_device num_threads batchsize img_dir det_config key_txt lite_benchmark_value"
<<
std
::
endl
;
exit
(
1
);
}
}
}
void
system
(
char
**
argv
){
std
::
string
det_model_file
=
argv
[
2
];
std
::
string
rec_model_file
=
argv
[
3
];
std
::
string
cls_model_file
=
argv
[
4
];
std
::
string
runtime_device
=
argv
[
5
];
std
::
string
precision
=
argv
[
6
];
std
::
string
num_threads
=
argv
[
7
];
std
::
string
batchsize
=
argv
[
8
];
std
::
string
img_dir
=
argv
[
9
];
std
::
string
det_config_path
=
argv
[
10
];
std
::
string
dict_path
=
argv
[
11
];
if
(
strcmp
(
argv
[
6
],
"FP32"
)
!=
0
&&
strcmp
(
argv
[
6
],
"INT8"
)
!=
0
)
{
std
::
cerr
<<
"Only support FP32 or INT8."
<<
std
::
endl
;
exit
(
1
);
}
std
::
vector
<
cv
::
String
>
cv_all_img_names
;
cv
::
glob
(
img_dir
,
cv_all_img_names
);
//// load config from txt file
auto
Config
=
LoadConfigTxt
(
"./
config
.txt"
);
auto
Config
=
LoadConfigTxt
(
det_
config
_path
);
int
use_direction_classify
=
int
(
Config
[
"use_direction_classify"
]);
auto
start
=
std
::
chrono
::
system_clock
::
now
();
auto
charactor_dict
=
ReadDict
(
dict_path
);
charactor_dict
.
insert
(
charactor_dict
.
begin
(),
"#"
);
// blank char for ctc
charactor_dict
.
push_back
(
" "
);
auto
det_predictor
=
loadModel
(
det_model_file
,
std
::
stoi
(
num_threads
));
auto
rec_predictor
=
loadModel
(
rec_model_file
,
std
::
stoi
(
num_threads
));
auto
cls_predictor
=
loadModel
(
cls_model_file
,
std
::
stoi
(
num_threads
));
std
::
vector
<
double
>
det_time_info
=
{
0
,
0
,
0
};
std
::
vector
<
double
>
rec_time_info
=
{
0
,
0
,
0
};
auto
det_predictor
=
loadModel
(
det_model_file
);
auto
rec_predictor
=
loadModel
(
rec_model_file
);
auto
cls_predictor
=
loadModel
(
cls_model_file
);
for
(
int
i
=
0
;
i
<
cv_all_img_names
.
size
();
++
i
)
{
std
::
cout
<<
"The predict img: "
<<
cv_all_img_names
[
i
]
<<
std
::
endl
;
cv
::
Mat
srcimg
=
cv
::
imread
(
cv_all_img_names
[
i
],
cv
::
IMREAD_COLOR
);
if
(
!
srcimg
.
data
)
{
std
::
cerr
<<
"[ERROR] image read failed! image path: "
<<
cv_all_img_names
[
i
]
<<
std
::
endl
;
exit
(
1
);
}
std
::
vector
<
double
>
det_times
;
auto
boxes
=
RunDetModel
(
det_predictor
,
srcimg
,
Config
,
&
det_times
);
std
::
vector
<
std
::
string
>
rec_text
;
std
::
vector
<
float
>
rec_text_score
;
std
::
vector
<
double
>
rec_times
;
RunRecModel
(
boxes
,
srcimg
,
rec_predictor
,
rec_text
,
rec_text_score
,
charactor_dict
,
cls_predictor
,
use_direction_classify
,
&
rec_times
);
//// visualization
auto
img_vis
=
Visualization
(
srcimg
,
boxes
);
//// print recognized text
for
(
int
i
=
0
;
i
<
rec_text
.
size
();
i
++
)
{
std
::
cout
<<
i
<<
"
\t
"
<<
rec_text
[
i
]
<<
"
\t
"
<<
rec_text_score
[
i
]
<<
std
::
endl
;
}
det_time_info
[
0
]
+=
det_times
[
0
];
det_time_info
[
1
]
+=
det_times
[
1
];
det_time_info
[
2
]
+=
det_times
[
2
];
rec_time_info
[
0
]
+=
rec_times
[
0
];
rec_time_info
[
1
]
+=
rec_times
[
1
];
rec_time_info
[
2
]
+=
rec_times
[
2
];
}
if
(
strcmp
(
argv
[
12
],
"True"
)
==
0
)
{
AutoLogger
autolog_det
(
det_model_file
,
runtime_device
,
std
::
stoi
(
num_threads
),
std
::
stoi
(
batchsize
),
"dynamic"
,
precision
,
det_time_info
,
cv_all_img_names
.
size
());
AutoLogger
autolog_rec
(
rec_model_file
,
runtime_device
,
std
::
stoi
(
num_threads
),
std
::
stoi
(
batchsize
),
"dynamic"
,
precision
,
rec_time_info
,
cv_all_img_names
.
size
());
autolog_det
.
report
();
std
::
cout
<<
std
::
endl
;
autolog_rec
.
report
();
}
}
void
det
(
int
argc
,
char
**
argv
)
{
std
::
string
det_model_file
=
argv
[
2
];
std
::
string
runtime_device
=
argv
[
3
];
std
::
string
precision
=
argv
[
4
];
std
::
string
num_threads
=
argv
[
5
];
std
::
string
batchsize
=
argv
[
6
];
std
::
string
img_dir
=
argv
[
7
];
std
::
string
det_config_path
=
argv
[
8
];
if
(
strcmp
(
argv
[
4
],
"FP32"
)
!=
0
&&
strcmp
(
argv
[
4
],
"INT8"
)
!=
0
)
{
std
::
cerr
<<
"Only support FP32 or INT8."
<<
std
::
endl
;
exit
(
1
);
}
std
::
vector
<
cv
::
String
>
cv_all_img_names
;
cv
::
glob
(
img_dir
,
cv_all_img_names
);
//// load config from txt file
auto
Config
=
LoadConfigTxt
(
det_config_path
);
auto
det_predictor
=
loadModel
(
det_model_file
,
std
::
stoi
(
num_threads
));
std
::
vector
<
double
>
time_info
=
{
0
,
0
,
0
};
for
(
int
i
=
0
;
i
<
cv_all_img_names
.
size
();
++
i
)
{
std
::
cout
<<
"The predict img: "
<<
cv_all_img_names
[
i
]
<<
std
::
endl
;
cv
::
Mat
srcimg
=
cv
::
imread
(
cv_all_img_names
[
i
],
cv
::
IMREAD_COLOR
);
if
(
!
srcimg
.
data
)
{
std
::
cerr
<<
"[ERROR] image read failed! image path: "
<<
cv_all_img_names
[
i
]
<<
std
::
endl
;
exit
(
1
);
}
std
::
vector
<
double
>
times
;
auto
boxes
=
RunDetModel
(
det_predictor
,
srcimg
,
Config
,
&
times
);
//// visualization
auto
img_vis
=
Visualization
(
srcimg
,
boxes
);
std
::
cout
<<
boxes
.
size
()
<<
" bboxes have detected:"
<<
std
::
endl
;
for
(
int
i
=
0
;
i
<
boxes
.
size
();
i
++
){
std
::
cout
<<
"The "
<<
i
<<
" box:"
<<
std
::
endl
;
for
(
int
j
=
0
;
j
<
4
;
j
++
){
for
(
int
k
=
0
;
k
<
2
;
k
++
){
std
::
cout
<<
boxes
[
i
][
j
][
k
]
<<
"
\t
"
;
}
}
std
::
cout
<<
std
::
endl
;
}
time_info
[
0
]
+=
times
[
0
];
time_info
[
1
]
+=
times
[
1
];
time_info
[
2
]
+=
times
[
2
];
}
if
(
strcmp
(
argv
[
9
],
"True"
)
==
0
)
{
AutoLogger
autolog
(
det_model_file
,
runtime_device
,
std
::
stoi
(
num_threads
),
std
::
stoi
(
batchsize
),
"dynamic"
,
precision
,
time_info
,
cv_all_img_names
.
size
());
autolog
.
report
();
}
}
void
rec
(
int
argc
,
char
**
argv
)
{
std
::
string
rec_model_file
=
argv
[
2
];
std
::
string
runtime_device
=
argv
[
3
];
std
::
string
precision
=
argv
[
4
];
std
::
string
num_threads
=
argv
[
5
];
std
::
string
batchsize
=
argv
[
6
];
std
::
string
img_dir
=
argv
[
7
];
std
::
string
dict_path
=
argv
[
8
];
if
(
strcmp
(
argv
[
4
],
"FP32"
)
!=
0
&&
strcmp
(
argv
[
4
],
"INT8"
)
!=
0
)
{
std
::
cerr
<<
"Only support FP32 or INT8."
<<
std
::
endl
;
exit
(
1
);
}
std
::
vector
<
cv
::
String
>
cv_all_img_names
;
cv
::
glob
(
img_dir
,
cv_all_img_names
);
auto
charactor_dict
=
ReadDict
(
dict_path
);
charactor_dict
.
insert
(
charactor_dict
.
begin
(),
"#"
);
// blank char for ctc
charactor_dict
.
push_back
(
" "
);
cv
::
Mat
srcimg
=
cv
::
imread
(
img_path
,
cv
::
IMREAD_COLOR
);
auto
boxes
=
RunDetModel
(
det_predictor
,
srcimg
,
Config
);
auto
rec_predictor
=
loadModel
(
rec_model_file
,
std
::
stoi
(
num_threads
));
std
::
vector
<
std
::
string
>
rec_text
;
std
::
vector
<
float
>
rec_text_score
;
std
::
shared_ptr
<
PaddlePredictor
>
cls_predictor
;
RunRecModel
(
boxes
,
srcimg
,
rec_predictor
,
rec_text
,
rec_text_score
,
charactor_dict
,
cls_predictor
,
use_direction_classify
);
std
::
vector
<
double
>
time_info
=
{
0
,
0
,
0
};
for
(
int
i
=
0
;
i
<
cv_all_img_names
.
size
();
++
i
)
{
std
::
cout
<<
"The predict img: "
<<
cv_all_img_names
[
i
]
<<
std
::
endl
;
cv
::
Mat
srcimg
=
cv
::
imread
(
cv_all_img_names
[
i
],
cv
::
IMREAD_COLOR
);
auto
end
=
std
::
chrono
::
system_clock
::
now
();
auto
duration
=
std
::
chrono
::
duration_cast
<
std
::
chrono
::
microseconds
>
(
end
-
start
);
if
(
!
srcimg
.
data
)
{
std
::
cerr
<<
"[ERROR] image read failed! image path: "
<<
cv_all_img_names
[
i
]
<<
std
::
endl
;
exit
(
1
);
}
//// visualization
auto
img_vis
=
Visualization
(
srcimg
,
boxes
);
int
width
=
srcimg
.
cols
;
int
height
=
srcimg
.
rows
;
std
::
vector
<
int
>
upper_left
=
{
0
,
0
};
std
::
vector
<
int
>
upper_right
=
{
width
,
0
};
std
::
vector
<
int
>
lower_right
=
{
width
,
height
};
std
::
vector
<
int
>
lower_left
=
{
0
,
height
};
std
::
vector
<
std
::
vector
<
int
>>
box
=
{
upper_left
,
upper_right
,
lower_right
,
lower_left
};
std
::
vector
<
std
::
vector
<
std
::
vector
<
int
>>>
boxes
=
{
box
};
std
::
vector
<
std
::
string
>
rec_text
;
std
::
vector
<
float
>
rec_text_score
;
std
::
vector
<
double
>
times
;
RunRecModel
(
boxes
,
srcimg
,
rec_predictor
,
rec_text
,
rec_text_score
,
charactor_dict
,
cls_predictor
,
0
,
&
times
);
//// print recognized text
for
(
int
i
=
0
;
i
<
rec_text
.
size
();
i
++
)
{
std
::
cout
<<
i
<<
"
\t
"
<<
rec_text
[
i
]
<<
"
\t
"
<<
rec_text_score
[
i
]
<<
std
::
endl
;
}
time_info
[
0
]
+=
times
[
0
];
time_info
[
1
]
+=
times
[
1
];
time_info
[
2
]
+=
times
[
2
];
}
// TODO: support autolog
if
(
strcmp
(
argv
[
9
],
"True"
)
==
0
)
{
AutoLogger
autolog
(
rec_model_file
,
runtime_device
,
std
::
stoi
(
num_threads
),
std
::
stoi
(
batchsize
),
"dynamic"
,
precision
,
time_info
,
cv_all_img_names
.
size
());
autolog
.
report
();
}
}
int
main
(
int
argc
,
char
**
argv
)
{
check_params
(
argc
,
argv
);
std
::
cout
<<
"mode: "
<<
argv
[
1
]
<<
endl
;
//// print recognized text
for
(
int
i
=
0
;
i
<
rec_text
.
size
();
i
++
)
{
std
::
cout
<<
i
<<
"
\t
"
<<
rec_text
[
i
]
<<
"
\t
"
<<
rec_text_score
[
i
]
<<
std
::
endl
;
if
(
strcmp
(
argv
[
1
],
"system"
)
==
0
)
{
system
(
argv
);
}
std
::
cout
<<
"花费了"
<<
double
(
duration
.
count
())
*
std
::
chrono
::
microseconds
::
period
::
num
/
std
::
chrono
::
microseconds
::
period
::
den
<<
"秒"
<<
std
::
endl
;
if
(
strcmp
(
argv
[
1
],
"det"
)
==
0
)
{
det
(
argc
,
argv
);
}
if
(
strcmp
(
argv
[
1
],
"rec"
)
==
0
)
{
rec
(
argc
,
argv
);
}
return
0
;
}
\ No newline at end of file
}
Prev
1
2
3
4
5
6
…
11
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