提交 acae8ea8 编写于 作者: L LDOUBLEV

update readme

上级 f3447747
......@@ -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.0f;
float dist = 0.0f;
......@@ -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;
......
# 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/12.jpg`为例,将测试的图像复制到`demo/cxx/ocr/debug/`文件夹下。
准备测试图像,以`PaddleOCR/doc/imgs/11.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 优化后的识别模型文件
| |--12.jpg 待测试图像
| |--11.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 ./12.jpg
./ocr_db_crnn ch_det_mv3_db_opt.nb ch_rec_mv3_crnn_opt.nb ./11.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.
先完成此消息的编辑!
想要评论请 注册