Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
s920243400
PaddleOCR
提交
69d78ddb
P
PaddleOCR
项目概览
s920243400
/
PaddleOCR
与 Fork 源项目一致
Fork自
PaddlePaddle / PaddleOCR
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
PaddleOCR
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
69d78ddb
编写于
2月 09, 2022
作者:
E
Evezerest
提交者:
GitHub
2月 09, 2022
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1092 from prettyocean85/develop
添加C++预测,批量识别代码
上级
6b44a969
b7cc06aa
变更
5
显示空白变更内容
内联
并排
Showing
5 changed file
with
118 addition
and
75 deletion
+118
-75
deploy/cpp_infer/include/config.h
deploy/cpp_infer/include/config.h
+4
-0
deploy/cpp_infer/include/ocr_rec.h
deploy/cpp_infer/include/ocr_rec.h
+3
-1
deploy/cpp_infer/src/main.cpp
deploy/cpp_infer/src/main.cpp
+3
-3
deploy/cpp_infer/src/ocr_rec.cpp
deploy/cpp_infer/src/ocr_rec.cpp
+107
-71
deploy/cpp_infer/tools/config.txt
deploy/cpp_infer/tools/config.txt
+1
-0
未找到文件。
deploy/cpp_infer/include/config.h
浏览文件 @
69d78ddb
...
...
@@ -63,6 +63,8 @@ public:
this
->
cls_thresh
=
stod
(
config_map_
[
"cls_thresh"
]);
this
->
rec_batch_num
=
stoi
(
config_map_
[
"rec_batch_num"
]);
this
->
visualize
=
bool
(
stoi
(
config_map_
[
"visualize"
]));
}
...
...
@@ -86,6 +88,8 @@ public:
double
det_db_unclip_ratio
=
2.0
;
int
rec_batch_num
=
30
;
std
::
string
det_model_dir
;
std
::
string
rec_model_dir
;
...
...
deploy/cpp_infer/include/ocr_rec.h
浏览文件 @
69d78ddb
...
...
@@ -40,13 +40,14 @@ public:
const
int
&
gpu_id
,
const
int
&
gpu_mem
,
const
int
&
cpu_math_library_num_threads
,
const
bool
&
use_mkldnn
,
const
bool
&
use_zero_copy_run
,
const
string
&
label_path
)
{
const
string
&
label_path
,
const
int
&
rec_batch_num
)
{
this
->
use_gpu_
=
use_gpu
;
this
->
gpu_id_
=
gpu_id
;
this
->
gpu_mem_
=
gpu_mem
;
this
->
cpu_math_library_num_threads_
=
cpu_math_library_num_threads
;
this
->
use_mkldnn_
=
use_mkldnn
;
this
->
use_zero_copy_run_
=
use_zero_copy_run
;
this
->
rec_batch_num_
=
rec_batch_num
;
this
->
label_list_
=
Utility
::
ReadDict
(
label_path
);
this
->
label_list_
.
push_back
(
" "
);
...
...
@@ -69,6 +70,7 @@ private:
int
cpu_math_library_num_threads_
=
4
;
bool
use_mkldnn_
=
false
;
bool
use_zero_copy_run_
=
false
;
int
rec_batch_num_
=
30
;
std
::
vector
<
std
::
string
>
label_list_
;
...
...
deploy/cpp_infer/src/main.cpp
浏览文件 @
69d78ddb
...
...
@@ -67,7 +67,7 @@ int main(int argc, char **argv) {
CRNNRecognizer
rec
(
config
.
rec_model_dir
,
config
.
use_gpu
,
config
.
gpu_id
,
config
.
gpu_mem
,
config
.
cpu_math_library_num_threads
,
config
.
use_mkldnn
,
config
.
use_zero_copy_run
,
config
.
char_list_file
);
config
.
char_list_file
,
config
.
rec_batch_num
);
#ifdef USE_MKL
#pragma omp parallel
...
...
@@ -91,11 +91,11 @@ int main(int argc, char **argv) {
auto
end
=
std
::
chrono
::
system_clock
::
now
();
auto
duration
=
std
::
chrono
::
duration_cast
<
std
::
chrono
::
microseconds
>
(
end
-
start
);
std
::
cout
<<
"
花费了
"
std
::
cout
<<
"
cost
"
<<
double
(
duration
.
count
())
*
std
::
chrono
::
microseconds
::
period
::
num
/
std
::
chrono
::
microseconds
::
period
::
den
<<
"
秒
"
<<
std
::
endl
;
<<
"
s
"
<<
std
::
endl
;
return
0
;
}
deploy/cpp_infer/src/ocr_rec.cpp
浏览文件 @
69d78ddb
...
...
@@ -14,6 +14,20 @@
#include <include/ocr_rec.h>
template
<
typename
T
>
vector
<
int
>
argsort
(
const
std
::
vector
<
T
>&
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
{
void
CRNNRecognizer
::
Run
(
std
::
vector
<
std
::
vector
<
std
::
vector
<
int
>>>
boxes
,
...
...
@@ -22,93 +36,114 @@ void CRNNRecognizer::Run(std::vector<std::vector<std::vector<int>>> boxes,
img
.
copyTo
(
srcimg
);
cv
::
Mat
crop_img
;
cv
::
Mat
resize_img
;
std
::
vector
<
float
>
width_list
;
std
::
vector
<
cv
::
Mat
>
img_list
;
std
::
cout
<<
"The predicted text is :"
<<
std
::
endl
;
int
index
=
0
;
for
(
int
i
=
boxes
.
size
()
-
1
;
i
>=
0
;
i
--
)
{
crop_img
=
GetRotateCropImage
(
srcimg
,
boxes
[
i
]);
if
(
cls
!=
nullptr
)
{
crop_img
=
cls
->
Run
(
crop_img
);
}
img_list
.
push_back
(
crop_img
);
float
wh_ratio
=
float
(
crop_img
.
cols
)
/
float
(
crop_img
.
rows
);
this
->
resize_op_
.
Run
(
crop_img
,
resize_img
,
wh_ratio
);
width_list
.
push_back
(
wh_ratio
);
}
//sort box
vector
<
int
>
sort_index
=
argsort
(
width_list
);
int
batch_num1
=
this
->
rec_batch_num_
;
//batchsize
std
::
cout
<<
"The predicted text is :"
<<
std
::
endl
;
int
index
=
0
;
int
beg_img_no
=
0
;
int
end_img_no
=
0
;
for
(
int
beg_img_no
=
0
;
beg_img_no
<
img_list
.
size
();
beg_img_no
+=
batch_num1
)
{
float
max_wh_ratio
=
0
;
end_img_no
=
min
((
int
)
boxes
.
size
(),
beg_img_no
+
batch_num1
);
int
batch_num
=
min
(
end_img_no
-
beg_img_no
,
batch_num1
);
max_wh_ratio
=
width_list
[
sort_index
[
end_img_no
-
1
]];
int
imgW1
=
int
(
32
*
max_wh_ratio
);
int
nqu
,
nra
;
nqu
=
imgW1
/
4
;
nra
=
imgW1
%
4
;
int
imgW
=
imgW1
;
if
(
nra
>
0
)
{
imgW
=
int
(
4
*
(
nqu
+
1
));
}
std
::
vector
<
float
>
input
(
batch_num
*
3
*
32
*
imgW
,
0.0
f
);
//batchsize input
for
(
int
i
=
beg_img_no
;
i
<
end_img_no
;
i
++
)
{
crop_img
=
img_list
[
sort_index
[
i
]];
this
->
resize_op_
.
Run
(
crop_img
,
resize_img
,
max_wh_ratio
);
//resize
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
());
cv
::
Mat
padding_im
;
cv
::
copyMakeBorder
(
resize_img
,
padding_im
,
0
,
0
,
0
,
int
(
imgW
-
resize_img
.
cols
),
cv
::
BORDER_CONSTANT
,
{
0
,
0
,
0
});
//padding image
// Inference.
if
(
this
->
use_zero_copy_run_
)
{
this
->
permute_op_
.
Run
(
&
padding_im
,
input
.
data
()
+
(
i
-
beg_img_no
)
*
3
*
padding_im
.
rows
*
padding_im
.
cols
);
}
auto
input_names
=
this
->
predictor_
->
GetInputNames
();
auto
input_t
=
this
->
predictor_
->
GetInputTensor
(
input_names
[
0
]);
input_t
->
Reshape
({
1
,
3
,
resize_img
.
rows
,
resize_img
.
cols
});
input_t
->
Reshape
({
batch_num
,
3
,
32
,
imgW
});
input_t
->
copy_from_cpu
(
input
.
data
());
this
->
predictor_
->
ZeroCopyRun
();
}
else
{
paddle
::
PaddleTensor
input_t
;
input_t
.
shape
=
{
1
,
3
,
resize_img
.
rows
,
resize_img
.
cols
};
input_t
.
data
=
paddle
::
PaddleBuf
(
input
.
data
(),
input
.
size
()
*
sizeof
(
float
));
input_t
.
dtype
=
PaddleDType
::
FLOAT32
;
std
::
vector
<
paddle
::
PaddleTensor
>
outputs
;
this
->
predictor_
->
Run
({
input_t
},
&
outputs
,
1
);
}
std
::
vector
<
int64_t
>
rec_idx
;
auto
output_names
=
this
->
predictor_
->
GetOutputNames
();
auto
output_t
=
this
->
predictor_
->
GetOutputTensor
(
output_names
[
0
]);
auto
rec_idx_lod
=
output_t
->
lod
();
auto
shape_out
=
output_t
->
shape
();
int
out_num
=
std
::
accumulate
(
shape_out
.
begin
(),
shape_out
.
end
(),
1
,
std
::
multiplies
<
int
>
());
rec_idx
.
resize
(
out_num
);
output_t
->
copy_to_cpu
(
rec_idx
.
data
());
std
::
vector
<
int
>
pred_idx
;
for
(
int
n
=
int
(
rec_idx_lod
[
0
][
0
]);
n
<
int
(
rec_idx_lod
[
0
][
1
]);
n
++
)
{
pred_idx
.
push_back
(
int
(
rec_idx
[
n
]));
}
if
(
pred_idx
.
size
()
<
1e-3
)
continue
;
auto
rec_idx_lod
=
output_t
->
lod
()[
0
];
index
+=
1
;
std
::
cout
<<
index
<<
"
\t
"
;
for
(
int
n
=
0
;
n
<
pred_idx
.
size
();
n
++
)
{
std
::
cout
<<
label_list_
[
pred_idx
[
n
]
];
std
::
vector
<
int
>
output_shape
=
output_t
->
shape
()
;
int
out_num
=
1
;
for
(
int
i
=
0
;
i
<
output_shape
.
size
();
++
i
)
{
out_num
*=
output_shape
[
i
];
}
rec_idx
.
resize
(
out_num
);
output_t
->
copy_to_cpu
(
rec_idx
.
data
());
//output data
std
::
vector
<
float
>
predict_batch
;
auto
output_t_1
=
this
->
predictor_
->
GetOutputTensor
(
output_names
[
1
]);
auto
predict_lod
=
output_t_1
->
lod
();
auto
predict_lod
=
output_t_1
->
lod
()
[
0
]
;
auto
predict_shape
=
output_t_1
->
shape
();
int
out_num_1
=
std
::
accumulate
(
predict_shape
.
begin
(),
predict_shape
.
end
(),
1
,
std
::
multiplies
<
int
>
());
int
out_num_1
=
1
;
for
(
int
i
=
0
;
i
<
predict_shape
.
size
();
++
i
)
{
out_num_1
*=
predict_shape
[
i
];
}
predict_batch
.
resize
(
out_num_1
);
output_t_1
->
copy_to_cpu
(
predict_batch
.
data
());
int
argmax_idx
;
int
blank
=
predict_shape
[
1
];
for
(
int
j
=
0
;
j
<
rec_idx_lod
.
size
()
-
1
;
j
++
)
{
std
::
vector
<
int
>
pred_idx
;
float
score
=
0.
f
;
int
count
=
0
;
float
max_value
=
0.0
f
;
for
(
int
n
=
int
(
rec_idx_lod
[
j
]);
n
<
int
(
rec_idx_lod
[
j
+
1
]);
n
++
)
{
pred_idx
.
push_back
(
int
(
rec_idx
[
n
]));
}
if
(
pred_idx
.
size
()
<
1e-3
)
continue
;
index
+=
1
;
std
::
cout
<<
index
<<
"
\t
"
;
for
(
int
n
=
0
;
n
<
pred_idx
.
size
();
n
++
)
{
std
::
cout
<<
label_list_
[
pred_idx
[
n
]];
}
for
(
int
n
=
predict_lod
[
0
][
0
];
n
<
predict_lod
[
0
][
1
]
-
1
;
n
++
)
{
for
(
int
n
=
predict_lod
[
j
];
n
<
predict_lod
[
j
+
1
]
-
1
;
n
++
)
{
argmax_idx
=
int
(
Utility
::
argmax
(
&
predict_batch
[
n
*
predict_shape
[
1
]],
&
predict_batch
[(
n
+
1
)
*
predict_shape
[
1
]]));
max_value
=
float
(
*
std
::
max_element
(
&
predict_batch
[
n
*
predict_shape
[
1
]],
&
predict_batch
[(
n
+
1
)
*
predict_shape
[
1
]]));
max_value
=
predict_batch
[
n
*
predict_shape
[
1
]
+
argmax_idx
];
if
(
blank
-
1
-
argmax_idx
>
1e-5
)
{
score
+=
max_value
;
count
+=
1
;
...
...
@@ -117,6 +152,7 @@ void CRNNRecognizer::Run(std::vector<std::vector<std::vector<int>>> boxes,
score
/=
count
;
std
::
cout
<<
"
\t
score: "
<<
score
<<
std
::
endl
;
}
}
}
void
CRNNRecognizer
::
LoadModel
(
const
std
::
string
&
model_dir
)
{
...
...
deploy/cpp_infer/tools/config.txt
浏览文件 @
69d78ddb
...
...
@@ -21,6 +21,7 @@ cls_thresh 0.9
# rec config
rec_model_dir ./inference/rec_crnn
char_list_file ../../ppocr/utils/ppocr_keys_v1.txt
rec_batch_num 30
# show the detection results
visualize 1
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录