Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
PaddleOCR
提交
acae8ea8
P
PaddleOCR
项目概览
PaddlePaddle
/
PaddleOCR
大约 1 年 前同步成功
通知
1528
Star
32962
Fork
6643
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
108
列表
看板
标记
里程碑
合并请求
7
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
PaddleOCR
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
108
Issue
108
列表
看板
标记
里程碑
合并请求
7
合并请求
7
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
acae8ea8
编写于
7月 07, 2020
作者:
L
LDOUBLEV
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
update readme
上级
f3447747
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
61 addition
and
57 deletion
+61
-57
deploy/imgs/demo.png
deploy/imgs/demo.png
+0
-0
deploy/lite/db_post_process.cc
deploy/lite/db_post_process.cc
+47
-47
deploy/lite/readme.md
deploy/lite/readme.md
+14
-10
未找到文件。
deploy/imgs/demo.png
0 → 100644
浏览文件 @
acae8ea8
997.6 KB
deploy/lite/db_post_process.cc
浏览文件 @
acae8ea8
...
...
@@ -12,13 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "db_post_process.h"
// NOLINT
#include "db_post_process.h" // NOLINT
#include <algorithm>
#include <utility>
void
GetContourArea
(
std
::
vector
<
std
::
vector
<
float
>>
box
,
float
unclip_ratio
,
float
&
distance
)
{
void
GetContourArea
(
std
::
vector
<
std
::
vector
<
float
>>
box
,
float
unclip_ratio
,
float
&
distance
)
{
int
pts_num
=
4
;
float
area
=
0.0
f
;
float
dist
=
0.0
f
;
...
...
@@ -78,34 +77,38 @@ std::vector<std::vector<float>> Mat2Vector(cv::Mat mat) {
}
bool
XsortFp32
(
std
::
vector
<
float
>
a
,
std
::
vector
<
float
>
b
)
{
if
(
a
[
0
]
!=
b
[
0
])
return
a
[
0
]
<
b
[
0
];
if
(
a
[
0
]
!=
b
[
0
])
return
a
[
0
]
<
b
[
0
];
return
false
;
}
bool
XsortInt
(
std
::
vector
<
int
>
a
,
std
::
vector
<
int
>
b
)
{
if
(
a
[
0
]
!=
b
[
0
])
return
a
[
0
]
<
b
[
0
];
if
(
a
[
0
]
!=
b
[
0
])
return
a
[
0
]
<
b
[
0
];
return
false
;
}
std
::
vector
<
std
::
vector
<
int
>>
OrderPointsClockwise
(
std
::
vector
<
std
::
vector
<
int
>>
pts
)
{
std
::
vector
<
std
::
vector
<
int
>>
OrderPointsClockwise
(
std
::
vector
<
std
::
vector
<
int
>>
pts
)
{
std
::
vector
<
std
::
vector
<
int
>>
box
=
pts
;
std
::
sort
(
box
.
begin
(),
box
.
end
(),
XsortInt
);
std
::
vector
<
std
::
vector
<
int
>>
leftmost
=
{
box
[
0
],
box
[
1
]};
std
::
vector
<
std
::
vector
<
int
>>
rightmost
=
{
box
[
2
],
box
[
3
]};
if
(
leftmost
[
0
][
1
]
>
leftmost
[
1
][
1
])
std
::
swap
(
leftmost
[
0
],
leftmost
[
1
]);
if
(
leftmost
[
0
][
1
]
>
leftmost
[
1
][
1
])
std
::
swap
(
leftmost
[
0
],
leftmost
[
1
]);
if
(
rightmost
[
0
][
1
]
>
rightmost
[
1
][
1
])
std
::
swap
(
rightmost
[
0
],
rightmost
[
1
]);
if
(
rightmost
[
0
][
1
]
>
rightmost
[
1
][
1
])
std
::
swap
(
rightmost
[
0
],
rightmost
[
1
]);
std
::
vector
<
std
::
vector
<
int
>>
rect
=
{
leftmost
[
0
],
rightmost
[
0
],
rightmost
[
1
],
leftmost
[
1
]};
std
::
vector
<
std
::
vector
<
int
>>
rect
=
{
leftmost
[
0
],
rightmost
[
0
],
rightmost
[
1
],
leftmost
[
1
]};
return
rect
;
}
std
::
vector
<
std
::
vector
<
float
>>
GetMiniBoxes
(
cv
::
RotatedRect
box
,
float
&
ssid
)
{
ssid
=
box
.
size
.
width
>=
box
.
size
.
height
?
box
.
size
.
height
:
box
.
size
.
width
;
std
::
vector
<
std
::
vector
<
float
>>
GetMiniBoxes
(
cv
::
RotatedRect
box
,
float
&
ssid
)
{
ssid
=
std
::
max
(
box
.
size
.
width
,
box
.
size
.
height
)
;
cv
::
Mat
points
;
cv
::
boxPoints
(
box
,
points
);
...
...
@@ -146,14 +149,14 @@ float BoxScoreFast(std::vector<std::vector<float>> box_array, cv::Mat pred) {
float
box_x
[
4
]
=
{
array
[
0
][
0
],
array
[
1
][
0
],
array
[
2
][
0
],
array
[
3
][
0
]};
float
box_y
[
4
]
=
{
array
[
0
][
1
],
array
[
1
][
1
],
array
[
2
][
1
],
array
[
3
][
1
]};
int
xmin
=
clamp
(
int
(
std
::
floorf
(
*
(
std
::
min_element
(
box_x
,
box_x
+
4
)))),
0
,
width
-
1
);
int
xmax
=
clamp
(
int
(
std
::
ceilf
(
*
(
std
::
max_element
(
box_x
,
box_x
+
4
)))),
0
,
width
-
1
);
int
ymin
=
clamp
(
int
(
std
::
floorf
(
*
(
std
::
min_element
(
box_y
,
box_y
+
4
)))),
0
,
height
-
1
);
int
ymax
=
clamp
(
int
(
std
::
ceilf
(
*
(
std
::
max_element
(
box_y
,
box_y
+
4
)))),
0
,
height
-
1
);
int
xmin
=
clamp
(
int
(
std
::
floorf
(
*
(
std
::
min_element
(
box_x
,
box_x
+
4
)))),
0
,
width
-
1
);
int
xmax
=
clamp
(
int
(
std
::
ceilf
(
*
(
std
::
max_element
(
box_x
,
box_x
+
4
)))),
0
,
width
-
1
);
int
ymin
=
clamp
(
int
(
std
::
floorf
(
*
(
std
::
min_element
(
box_y
,
box_y
+
4
)))),
0
,
height
-
1
);
int
ymax
=
clamp
(
int
(
std
::
ceilf
(
*
(
std
::
max_element
(
box_y
,
box_y
+
4
)))),
0
,
height
-
1
);
cv
::
Mat
mask
;
mask
=
cv
::
Mat
::
zeros
(
ymax
-
ymin
+
1
,
xmax
-
xmin
+
1
,
CV_8UC1
);
...
...
@@ -163,7 +166,7 @@ float BoxScoreFast(std::vector<std::vector<float>> box_array, cv::Mat pred) {
root_point
[
1
]
=
cv
::
Point
(
int
(
array
[
1
][
0
])
-
xmin
,
int
(
array
[
1
][
1
])
-
ymin
);
root_point
[
2
]
=
cv
::
Point
(
int
(
array
[
2
][
0
])
-
xmin
,
int
(
array
[
2
][
1
])
-
ymin
);
root_point
[
3
]
=
cv
::
Point
(
int
(
array
[
3
][
0
])
-
xmin
,
int
(
array
[
3
][
1
])
-
ymin
);
const
cv
::
Point
*
ppt
[
1
]
=
{
root_point
};
const
cv
::
Point
*
ppt
[
1
]
=
{
root_point
};
int
npt
[]
=
{
4
};
cv
::
fillPoly
(
mask
,
ppt
,
npt
,
1
,
cv
::
Scalar
(
1
));
...
...
@@ -175,10 +178,9 @@ float BoxScoreFast(std::vector<std::vector<float>> box_array, cv::Mat pred) {
return
score
;
}
std
::
vector
<
std
::
vector
<
std
::
vector
<
int
>>>
BoxesFromBitmap
(
const
cv
::
Mat
pred
,
const
cv
::
Mat
bitmap
,
std
::
map
<
std
::
string
,
double
>
Config
)
{
std
::
vector
<
std
::
vector
<
std
::
vector
<
int
>>>
BoxesFromBitmap
(
const
cv
::
Mat
pred
,
const
cv
::
Mat
bitmap
,
std
::
map
<
std
::
string
,
double
>
Config
)
{
const
int
min_size
=
3
;
const
int
max_candidates
=
1000
;
const
float
box_thresh
=
float
(
Config
[
"det_db_box_thresh"
]);
...
...
@@ -190,8 +192,8 @@ std::vector<std::vector<std::vector<int>>> BoxesFromBitmap(
std
::
vector
<
std
::
vector
<
cv
::
Point
>>
contours
;
std
::
vector
<
cv
::
Vec4i
>
hierarchy
;
cv
::
findContours
(
bitmap
,
contours
,
hierarchy
,
cv
::
RETR_LIST
,
cv
::
CHAIN_APPROX_SIMPLE
);
cv
::
findContours
(
bitmap
,
contours
,
hierarchy
,
cv
::
RETR_LIST
,
cv
::
CHAIN_APPROX_SIMPLE
);
int
num_contours
=
contours
.
size
()
>=
max_candidates
?
max_candidates
:
contours
.
size
();
...
...
@@ -213,7 +215,8 @@ std::vector<std::vector<std::vector<int>>> BoxesFromBitmap(
float
score
;
score
=
BoxScoreFast
(
array
,
pred
);
// end box_score_fast
if
(
score
<
box_thresh
)
continue
;
if
(
score
<
box_thresh
)
continue
;
// start for unclip
cv
::
RotatedRect
points
=
Unclip
(
box_for_unclip
,
unclip_ratio
);
...
...
@@ -222,35 +225,31 @@ std::vector<std::vector<std::vector<int>>> BoxesFromBitmap(
cv
::
RotatedRect
clipbox
=
points
;
auto
cliparray
=
GetMiniBoxes
(
clipbox
,
ssid
);
if
(
ssid
<
min_size
+
2
)
continue
;
if
(
ssid
<
min_size
+
2
)
continue
;
int
dest_width
=
pred
.
cols
;
int
dest_height
=
pred
.
rows
;
std
::
vector
<
std
::
vector
<
int
>>
intcliparray
;
for
(
int
num_pt
=
0
;
num_pt
<
4
;
num_pt
++
)
{
std
::
vector
<
int
>
a
{
int
(
clamp
(
roundf
(
cliparray
[
num_pt
][
0
]
/
float
(
width
)
*
float
(
dest_width
)),
float
(
0
),
float
(
dest_width
))),
int
(
clamp
(
roundf
(
cliparray
[
num_pt
][
1
]
/
float
(
height
)
*
float
(
dest_height
)),
float
(
0
),
float
(
dest_height
)))};
std
::
vector
<
int
>
a
{
int
(
clamp
(
roundf
(
cliparray
[
num_pt
][
0
]
/
float
(
width
)
*
float
(
dest_width
)),
float
(
0
),
float
(
dest_width
))),
int
(
clamp
(
roundf
(
cliparray
[
num_pt
][
1
]
/
float
(
height
)
*
float
(
dest_height
)),
float
(
0
),
float
(
dest_height
)))};
intcliparray
.
push_back
(
a
);
}
boxes
.
push_back
(
intcliparray
);
}
// end for
}
// end for
return
boxes
;
}
std
::
vector
<
std
::
vector
<
std
::
vector
<
int
>>>
FilterTagDetRes
(
std
::
vector
<
std
::
vector
<
std
::
vector
<
int
>>>
boxes
,
float
ratio_h
,
float
ratio_w
,
cv
::
Mat
srcimg
)
{
std
::
vector
<
std
::
vector
<
std
::
vector
<
int
>>>
FilterTagDetRes
(
std
::
vector
<
std
::
vector
<
std
::
vector
<
int
>>>
boxes
,
float
ratio_h
,
float
ratio_w
,
cv
::
Mat
srcimg
)
{
int
oriimg_h
=
srcimg
.
rows
;
int
oriimg_w
=
srcimg
.
cols
;
...
...
@@ -272,7 +271,8 @@ std::vector<std::vector<std::vector<int>>> FilterTagDetRes(
pow
(
boxes
[
n
][
0
][
1
]
-
boxes
[
n
][
1
][
1
],
2
)));
rect_height
=
int
(
sqrt
(
pow
(
boxes
[
n
][
0
][
0
]
-
boxes
[
n
][
3
][
0
],
2
)
+
pow
(
boxes
[
n
][
0
][
1
]
-
boxes
[
n
][
3
][
1
],
2
)));
if
(
rect_width
<=
10
||
rect_height
<=
10
)
continue
;
if
(
rect_width
<=
10
||
rect_height
<=
10
)
continue
;
root_points
.
push_back
(
boxes
[
n
]);
}
return
root_points
;
...
...
deploy/lite/readme.md
浏览文件 @
acae8ea8
# PaddleOCR 模型部署
PaddleOCR是集训练、预测、部署于一体的实用OCR工具库。本教程将介绍在安卓移动端部署PaddleOCR超轻量中文检测、识别模型的主要流程。
PaddleOCR是集训练、预测、
端侧
部署于一体的实用OCR工具库。本教程将介绍在安卓移动端部署PaddleOCR超轻量中文检测、识别模型的主要流程。
## 1. 准备环境
...
...
@@ -144,9 +144,9 @@ wget https://paddleocr.bj.bcebos.com/ch_models/ch_rec_mv3_crnn_infer.tar && tar
# 进入OCR demo的工作目录
cd demo/cxx/ocr/
# 将C++预测动态库so文件复制到debug文件夹中
cp ../../../cxx/lib/libpaddle_light_api_shared.so ./debug/
cp ../../../
../
cxx/lib/libpaddle_light_api_shared.so ./debug/
```
准备测试图像,以
`PaddleOCR/doc/imgs/1
2
.jpg`
为例,将测试的图像复制到
`demo/cxx/ocr/debug/`
文件夹下。
准备测试图像,以
`PaddleOCR/doc/imgs/1
1
.jpg`
为例,将测试的图像复制到
`demo/cxx/ocr/debug/`
文件夹下。
准备字典文件,中文超轻量模型的字典文件是
`PaddleOCR/ppocr/utils/ppocr_keys_v1.txt`
,将其复制到
`demo/cxx/ocr/debug/`
文件夹下。
执行完成后,ocr文件夹下将有如下文件格式:
...
...
@@ -156,16 +156,17 @@ demo/cxx/ocr/
|-- debug/
| |--ch_det_mv3_db_opt.nb 优化后的检测模型文件
| |--ch_rec_mv3_crnn_opt.nb 优化后的识别模型文件
| |--1
2
.jpg 待测试图像
| |--1
1
.jpg 待测试图像
| |--ppocr_keys_v1.txt 字典文件
| |--libpaddle_light_api_shared.so C++预测库文件
|--
utils/
|
|-- clipper.cpp Clipper库的cpp
文件
|
|-- clipper.hpp Clipper库的hpp文件
|
|-- crnn_process.cpp 识别模型CRNN的预处理和后处理cpp
文件
|
|-- db_post_process.cpp 检测模型DB的后处理cpp文件
|--
config.txt DB-CRNN超参数配置
|
-- crnn_process.cc 识别模型CRNN的预处理和后处理
文件
|
-- crnn_process.h
|
-- db_post_process.cc 检测模型DB的后处理
文件
|
-- db_post_process.h
|-- Makefile 编译文件
|-- ocr_db_crnn.cc C++预测源文件
```
5.
启动调试
...
...
@@ -184,7 +185,10 @@ demo/cxx/ocr/
adb shell
cd /data/local/tmp/debug
export LD_LIBRARY_PATH=/data/local/tmp/debug:$LD_LIBRARY_PATH
./ocr_db_crnn ch_det_mv3_db_opt.nb ch_rec_mv3_crnn_opt.nb ./1
2.jpg
./ocr_db_crnn ch_det_mv3_db_opt.nb ch_rec_mv3_crnn_opt.nb ./1
1.jpg ppocr_keys_v1.txt
```
如果对代码做了修改,则需要重新编译并push到手机上。
运行效果如下:
!
[](
..imgs/demo.png
)
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录