提交 9d16c117 编写于 作者: littletomatodonkey's avatar littletomatodonkey

fix cpp infer

上级 69a7a140
......@@ -36,16 +36,13 @@ namespace PaddleOCR {
class DBDetector {
public:
explicit DBDetector(const std::string &model_dir, const bool &use_gpu = false,
const int &gpu_id = 0, const int &gpu_mem = 4000,
const int &cpu_math_library_num_threads = 4,
const int &max_side_len = 960,
const double &det_db_thresh = 0.3,
const double &det_db_box_thresh = 0.5,
const double &det_db_unclip_ratio = 2.0,
const bool &visualize = true) {
LoadModel(model_dir);
explicit DBDetector(const std::string &model_dir, const bool &use_gpu,
const int &gpu_id, const int &gpu_mem,
const int &cpu_math_library_num_threads,
const int &max_side_len, const double &det_db_thresh,
const double &det_db_box_thresh,
const double &det_db_unclip_ratio,
const bool &visualize) {
this->use_gpu_ = use_gpu;
this->gpu_id_ = gpu_id;
this->gpu_mem_ = gpu_mem;
......@@ -58,6 +55,8 @@ public:
this->det_db_unclip_ratio_ = det_db_unclip_ratio;
this->visualize_ = visualize;
LoadModel(model_dir);
}
// Load Paddle inference model
......
......@@ -35,19 +35,18 @@ namespace PaddleOCR {
class CRNNRecognizer {
public:
explicit CRNNRecognizer(
const std::string &model_dir, const bool &use_gpu = false,
const int &gpu_id = 0, const int &gpu_mem = 4000,
const int &cpu_math_library_num_threads = 4,
const string &label_path = "./tools/ppocr_keys_v1.txt") {
LoadModel(model_dir);
explicit CRNNRecognizer(const std::string &model_dir, const bool &use_gpu,
const int &gpu_id, const int &gpu_mem,
const int &cpu_math_library_num_threads,
const string &label_path) {
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->label_list_ = Utility::ReadDict(label_path);
LoadModel(model_dir);
}
// Load Paddle inference model
......
......@@ -36,21 +36,21 @@ namespace PaddleOCR {
class PostProcessor {
public:
void GetContourArea(float **box, float unclip_ratio, float &distance);
void GetContourArea(const std::vector<std::vector<float>> &box,
float unclip_ratio, float &distance);
cv::RotatedRect UnClip(float **box, const float &unclip_ratio);
cv::RotatedRect UnClip(std::vector<std::vector<float>> box,
const float &unclip_ratio);
float **Mat2Vec(cv::Mat mat);
void quickSort_vector(std::vector<std::vector<int>> &box, int l, int r,
int axis);
std::vector<std::vector<int>>
order_points_clockwise(std::vector<std::vector<int>> pts);
OrderPointsClockwise(std::vector<std::vector<int>> pts);
float **GetMiniBoxes(cv::RotatedRect box, float &ssid);
std::vector<std::vector<float>> GetMiniBoxes(cv::RotatedRect box,
float &ssid);
float BoxScoreFast(float **box_array, cv::Mat pred);
float BoxScoreFast(std::vector<std::vector<float>> box_array, cv::Mat pred);
std::vector<std::vector<std::vector<int>>>
BoxesFromBitmap(const cv::Mat pred, const cv::Mat bitmap,
......@@ -61,7 +61,11 @@ public:
float ratio_h, float ratio_w, cv::Mat srcimg);
private:
void quickSort(float **s, int l, int r);
static bool XsortInt(std::vector<int> a, std::vector<int> b);
static bool XsortFp32(std::vector<float> a, std::vector<float> b);
std::vector<std::vector<float>> Mat2Vector(cv::Mat mat);
inline int _max(int a, int b) { return a >= b ? a : b; }
......
......@@ -22,7 +22,7 @@ tar -xf 3.4.7.tar.gz
* 编译opencv,设置opencv源码路径(`root_path`)以及安装路径(`install_path`)。进入opencv源码路径下,按照下面的方式进行编译。
```shell
root_path=/paddle/libs/opencv-3.4.7
root_path=your_opencv_root_path
install_path=${root_path}/opencv3
rm -rf build
......@@ -51,6 +51,9 @@ make -j
make install
```
其中`root_path`为下载的opencv源码路径,`install_path`为opencv的安装路径,`make install`完成之后,会在该文件夹下生成opencv头文件和库文件,用于后面的OCR代码编译。
最终在安装路径下的文件结构如下所示。
```
......@@ -62,8 +65,29 @@ opencv3/
|-- share
```
### 1.2 编译Paddle预测库
### 1.2 下载或者编译Paddle预测库
* 有2种方式获取Paddle预测库,下面进行详细介绍。
#### 1.2.1 直接下载安装
* [Paddle预测库官网](https://www.paddlepaddle.org.cn/documentation/docs/zh/advanced_guide/inference_deployment/inference/build_and_install_lib_cn.html)上提供了不同cuda版本的Linux预测库,可以直接下载使用。
* 如果cuda版本为cuda9.0,1.8.2版本的Paddle预测库可以从这里下载:[下载地址](https://paddle-inference-lib.bj.bcebos.com/1.8.2-gpu-cuda9-cudnn7-avx-mkl/fluid_inference.tgz)
* 如果cuda版本为cuda10.0,1.8.2版本的Paddle预测库可以从这里下载:[下载地址](https://paddle-inference-lib.bj.bcebos.com/1.8.2-gpu-cuda10-cudnn7-avx-mkl/fluid_inference.tgz)
* 更多版本的预测库可以在官网查看下载。
* 下载之后使用下面的方法解压
```
tar -xf fluid_inference.tgz
```
最终会在当前的文件夹中生成`fluid_inference/`的子文件夹。
#### 1.2.2 预测库源码编译
* 如果希望获取最新预测库特性,可以从Paddle github上克隆最新代码,源码编译预测库。
* 可以参考[Paddle预测库官网](https://www.paddlepaddle.org.cn/documentation/docs/zh/advanced_guide/inference_deployment/inference/build_and_install_lib_cn.html)的说明,从github上获取Paddle代码,然后进行编译,生成最新的预测库。使用git获取代码方法如下。
```shell
......@@ -80,7 +104,7 @@ cd build
cmake .. \
-DWITH_CONTRIB=OFF \
-DWITH_MKL=ON \
-DWITH_MKLDNN=OFF \
-DWITH_MKLDNN=ON \
-DWITH_TESTING=OFF \
-DCMAKE_BUILD_TYPE=Release \
-DWITH_INFERENCE_API_TEST=OFF \
......@@ -132,6 +156,15 @@ inference/
sh tools/build.sh
```
具体地,`tools/build.sh`中内容如下。
```shell
c
```
`OPENCV_DIR`为opencv编译安装的地址;`LIB_DIR`为下载(`fluid_inference`文件夹)或者编译生成的Paddle预测库地址(`build/fluid_inference_install_dir`文件夹);`CUDA_LIB_DIR`为cuda库文件地址,在docker中;为`/usr/local/cuda/lib64``CUDNN_LIB_DIR`为cudnn库文件地址,在docker中为`/usr/lib/x86_64-linux-gnu/`
* 编译完成之后,会在`build`文件夹下生成一个名为`ocr_system`的可执行文件。
......
......@@ -46,8 +46,6 @@ int main(int argc, char **argv) {
std::string img_path(argv[2]);
auto start = std::chrono::system_clock::now();
cv::Mat srcimg = cv::imread(img_path, cv::IMREAD_COLOR);
DBDetector det(config.det_model_dir, config.use_gpu, config.gpu_id,
......@@ -59,6 +57,7 @@ int main(int argc, char **argv) {
config.gpu_mem, config.cpu_math_library_num_threads,
config.char_list_file);
auto start = std::chrono::system_clock::now();
std::vector<std::vector<std::vector<int>>> boxes;
det.Run(srcimg, boxes);
......
......@@ -12,22 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "opencv2/core.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
#include "paddle_api.h"
#include "paddle_inference_api.h"
#include <chrono>
#include <iomanip>
#include <iostream>
#include <ostream>
#include <vector>
#include <cstring>
#include <fstream>
#include <numeric>
#include <include/ocr_det.h>
#include <stdlib.h>
namespace PaddleOCR {
......
......@@ -16,8 +16,8 @@
namespace PaddleOCR {
void PostProcessor::GetContourArea(float **box, float unclip_ratio,
float &distance) {
void PostProcessor::GetContourArea(const std::vector<std::vector<float>> &box,
float unclip_ratio, float &distance) {
int pts_num = 4;
float area = 0.0f;
float dist = 0.0f;
......@@ -34,7 +34,8 @@ void PostProcessor::GetContourArea(float **box, float unclip_ratio,
distance = area * unclip_ratio / dist;
}
cv::RotatedRect PostProcessor::UnClip(float **box, const float &unclip_ratio) {
cv::RotatedRect PostProcessor::UnClip(std::vector<std::vector<float>> box,
const float &unclip_ratio) {
float distance = 1.0;
GetContourArea(box, unclip_ratio, distance);
......@@ -74,53 +75,11 @@ float **PostProcessor::Mat2Vec(cv::Mat mat) {
return array;
}
void PostProcessor::quickSort(float **s, int l, int r) {
if (l < r) {
int i = l, j = r;
float x = s[l][0];
float *xp = s[l];
while (i < j) {
while (i < j && s[j][0] >= x)
j--;
if (i < j)
std::swap(s[i++], s[j]);
while (i < j && s[i][0] < x)
i++;
if (i < j)
std::swap(s[j--], s[i]);
}
s[i] = xp;
quickSort(s, l, i - 1);
quickSort(s, i + 1, r);
}
}
void PostProcessor::quickSort_vector(std::vector<std::vector<int>> &box, int l,
int r, int axis) {
if (l < r) {
int i = l, j = r;
int x = box[l][axis];
std::vector<int> xp(box[l]);
while (i < j) {
while (i < j && box[j][axis] >= x)
j--;
if (i < j)
std::swap(box[i++], box[j]);
while (i < j && box[i][axis] < x)
i++;
if (i < j)
std::swap(box[j--], box[i]);
}
box[i] = xp;
quickSort_vector(box, l, i - 1, axis);
quickSort_vector(box, i + 1, r, axis);
}
}
std::vector<std::vector<int>>
PostProcessor::order_points_clockwise(std::vector<std::vector<int>> pts) {
PostProcessor::OrderPointsClockwise(std::vector<std::vector<int>> pts) {
std::vector<std::vector<int>> box = pts;
quickSort_vector(box, 0, int(box.size() - 1), 0);
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]};
......@@ -135,16 +94,44 @@ PostProcessor::order_points_clockwise(std::vector<std::vector<int>> pts) {
return rect;
}
float **PostProcessor::GetMiniBoxes(cv::RotatedRect box, float &ssid) {
ssid = box.size.width >= box.size.height ? box.size.height : box.size.width;
std::vector<std::vector<float>> PostProcessor::Mat2Vector(cv::Mat mat) {
std::vector<std::vector<float>> img_vec;
std::vector<float> tmp;
for (int i = 0; i < mat.rows; ++i) {
tmp.clear();
for (int j = 0; j < mat.cols; ++j) {
tmp.push_back(mat.at<float>(i, j));
}
img_vec.push_back(tmp);
}
return img_vec;
}
bool PostProcessor::XsortFp32(std::vector<float> a, std::vector<float> b) {
if (a[0] != b[0])
return a[0] < b[0];
return false;
}
bool PostProcessor::XsortInt(std::vector<int> a, std::vector<int> b) {
if (a[0] != b[0])
return a[0] < b[0];
return false;
}
std::vector<std::vector<float>> PostProcessor::GetMiniBoxes(cv::RotatedRect box,
float &ssid) {
ssid = std::max(box.size.width, box.size.height);
cv::Mat points;
cv::boxPoints(box, points);
// sorted box points
auto array = Mat2Vec(points);
quickSort(array, 0, 3);
float *idx1 = array[0], *idx2 = array[1], *idx3 = array[2], *idx4 = array[3];
auto array = Mat2Vector(points);
std::sort(array.begin(), array.end(), XsortFp32);
std::vector<float> idx1 = array[0], idx2 = array[1], idx3 = array[2],
idx4 = array[3];
if (array[3][1] <= array[2][1]) {
idx2 = array[3];
idx3 = array[2];
......@@ -168,7 +155,8 @@ float **PostProcessor::GetMiniBoxes(cv::RotatedRect box, float &ssid) {
return array;
}
float PostProcessor::BoxScoreFast(float **box_array, cv::Mat pred) {
float PostProcessor::BoxScoreFast(std::vector<std::vector<float>> box_array,
cv::Mat pred) {
auto array = box_array;
int width = pred.cols;
int height = pred.rows;
......@@ -280,7 +268,7 @@ PostProcessor::FilterTagDetRes(std::vector<std::vector<std::vector<int>>> boxes,
std::vector<std::vector<std::vector<int>>> root_points;
for (int n = 0; n < boxes.size(); n++) {
boxes[n] = order_points_clockwise(boxes[n]);
boxes[n] = OrderPointsClockwise(boxes[n]);
for (int m = 0; m < boxes[0].size(); m++) {
boxes[n][m][0] /= ratio_w;
boxes[n][m][1] /= ratio_h;
......
OPENCV_DIR=/paddle/libs/opencv-3.4.7/opencv3
LIB_DIR=/paddle/code/gry/Paddle/build/fluid_inference_install_dir/
CUDA_LIB_DIR=/usr/local/cuda/lib64
CUDNN_LIB_DIR=/usr/lib/x86_64-linux-gnu/
TENSORRT_ROOT_DIR=YOUR_TENSORRT_ROOT_DIR
OPENCV_DIR=your_opencv_dir
LIB_DIR=your_paddle_inference_dir
CUDA_LIB_DIR=your_cuda_lib_dir
CUDNN_LIB_DIR=/your_cudnn_lib_dir
BUILD_DIR=build
rm -rf ${BUILD_DIR}
......@@ -19,8 +18,5 @@ cmake .. \
-DOPENCV_DIR=${OPENCV_DIR} \
-DCUDNN_LIB=${CUDNN_LIB_DIR} \
-DCUDA_LIB=${CUDA_LIB_DIR} \
-DTENSORRT_ROOT=YOUR_TENSORRT_ROOT_DIR
make -j
......@@ -13,7 +13,7 @@ det_model_dir ./inference/det_db
# rec config
rec_model_dir ./inference/rec_crnn
char_list_file ./tools/ppocr_keys_v1.txt
char_list_file ../../ppocr/utils/ppocr_keys_v1.txt
img_path ../../doc/imgs/11.jpg
# show the detection results
......
'
贿
2
0
8
-
7
>
:
]
,
蹿
1
3
!
诿
线
尿
|
;
H
.
/
*
忿
齿
西
5
4
亿
(
访
6
)
稿
s
u
[
9
岿
广
S
Y
F
D
A
P
T
湿
窿
@
丿
沿
使
绿
%
"
婿
r
=
饿
ˇ
q
÷
椿
寿
?
便
殿
J
l
&
驿
x
耀
仿
鸿
廿
z
±
e
t
§
姿
b
<
退
L
鹿
w
i
h
+
I
B
N
^
_
M
鱿
怀
}
~
Z
槿
C
o
E
f
\
屿
U
a
p
y
n
g
竿
Q
羿
O
宿
k
$
c
v
W
穿
×
轿
R
G
ˉ
d
°
K
X
m
涿
`
V
#
簿
{
j
·
Ë
¥
π
é
Λ
Ο
α
 
鴿
è
Ü
И
»
ä
ɔ
´
í
É
ʌ
Я
Й
粿
®
З
β
á
Ó
ò
貿
𣇉
г
楿
滿
Φ
ε
ü
調
ˋ
ā
ú
ó
ē
Ω
П
ǐ
ō
ǒ
μ
à
ɡ
ī
²
駿
θ
ū
ì
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册