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

fix cpp infer

上级 69a7a140
...@@ -36,16 +36,13 @@ namespace PaddleOCR { ...@@ -36,16 +36,13 @@ namespace PaddleOCR {
class DBDetector { class DBDetector {
public: public:
explicit DBDetector(const std::string &model_dir, const bool &use_gpu = false, explicit DBDetector(const std::string &model_dir, const bool &use_gpu,
const int &gpu_id = 0, const int &gpu_mem = 4000, const int &gpu_id, const int &gpu_mem,
const int &cpu_math_library_num_threads = 4, const int &cpu_math_library_num_threads,
const int &max_side_len = 960, const int &max_side_len, const double &det_db_thresh,
const double &det_db_thresh = 0.3, const double &det_db_box_thresh,
const double &det_db_box_thresh = 0.5, const double &det_db_unclip_ratio,
const double &det_db_unclip_ratio = 2.0, const bool &visualize) {
const bool &visualize = true) {
LoadModel(model_dir);
this->use_gpu_ = use_gpu; this->use_gpu_ = use_gpu;
this->gpu_id_ = gpu_id; this->gpu_id_ = gpu_id;
this->gpu_mem_ = gpu_mem; this->gpu_mem_ = gpu_mem;
...@@ -58,6 +55,8 @@ public: ...@@ -58,6 +55,8 @@ public:
this->det_db_unclip_ratio_ = det_db_unclip_ratio; this->det_db_unclip_ratio_ = det_db_unclip_ratio;
this->visualize_ = visualize; this->visualize_ = visualize;
LoadModel(model_dir);
} }
// Load Paddle inference model // Load Paddle inference model
......
...@@ -35,19 +35,18 @@ namespace PaddleOCR { ...@@ -35,19 +35,18 @@ namespace PaddleOCR {
class CRNNRecognizer { class CRNNRecognizer {
public: public:
explicit CRNNRecognizer( explicit CRNNRecognizer(const std::string &model_dir, const bool &use_gpu,
const std::string &model_dir, const bool &use_gpu = false, const int &gpu_id, const int &gpu_mem,
const int &gpu_id = 0, const int &gpu_mem = 4000, const int &cpu_math_library_num_threads,
const int &cpu_math_library_num_threads = 4, const string &label_path) {
const string &label_path = "./tools/ppocr_keys_v1.txt") {
LoadModel(model_dir);
this->use_gpu_ = use_gpu; this->use_gpu_ = use_gpu;
this->gpu_id_ = gpu_id; this->gpu_id_ = gpu_id;
this->gpu_mem_ = gpu_mem; this->gpu_mem_ = gpu_mem;
this->cpu_math_library_num_threads_ = cpu_math_library_num_threads; this->cpu_math_library_num_threads_ = cpu_math_library_num_threads;
this->label_list_ = Utility::ReadDict(label_path); this->label_list_ = Utility::ReadDict(label_path);
LoadModel(model_dir);
} }
// Load Paddle inference model // Load Paddle inference model
......
...@@ -36,21 +36,21 @@ namespace PaddleOCR { ...@@ -36,21 +36,21 @@ namespace PaddleOCR {
class PostProcessor { class PostProcessor {
public: 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); 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>> 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>>> std::vector<std::vector<std::vector<int>>>
BoxesFromBitmap(const cv::Mat pred, const cv::Mat bitmap, BoxesFromBitmap(const cv::Mat pred, const cv::Mat bitmap,
...@@ -61,7 +61,11 @@ public: ...@@ -61,7 +61,11 @@ public:
float ratio_h, float ratio_w, cv::Mat srcimg); float ratio_h, float ratio_w, cv::Mat srcimg);
private: 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; } inline int _max(int a, int b) { return a >= b ? a : b; }
......
...@@ -22,7 +22,7 @@ tar -xf 3.4.7.tar.gz ...@@ -22,7 +22,7 @@ tar -xf 3.4.7.tar.gz
* 编译opencv,设置opencv源码路径(`root_path`)以及安装路径(`install_path`)。进入opencv源码路径下,按照下面的方式进行编译。 * 编译opencv,设置opencv源码路径(`root_path`)以及安装路径(`install_path`)。进入opencv源码路径下,按照下面的方式进行编译。
```shell ```shell
root_path=/paddle/libs/opencv-3.4.7 root_path=your_opencv_root_path
install_path=${root_path}/opencv3 install_path=${root_path}/opencv3
rm -rf build rm -rf build
...@@ -51,6 +51,9 @@ make -j ...@@ -51,6 +51,9 @@ make -j
make install make install
``` ```
其中`root_path`为下载的opencv源码路径,`install_path`为opencv的安装路径,`make install`完成之后,会在该文件夹下生成opencv头文件和库文件,用于后面的OCR代码编译。
最终在安装路径下的文件结构如下所示。 最终在安装路径下的文件结构如下所示。
``` ```
...@@ -62,8 +65,29 @@ opencv3/ ...@@ -62,8 +65,29 @@ opencv3/
|-- share |-- 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获取代码方法如下。 * 可以参考[Paddle预测库官网](https://www.paddlepaddle.org.cn/documentation/docs/zh/advanced_guide/inference_deployment/inference/build_and_install_lib_cn.html)的说明,从github上获取Paddle代码,然后进行编译,生成最新的预测库。使用git获取代码方法如下。
```shell ```shell
...@@ -80,7 +104,7 @@ cd build ...@@ -80,7 +104,7 @@ cd build
cmake .. \ cmake .. \
-DWITH_CONTRIB=OFF \ -DWITH_CONTRIB=OFF \
-DWITH_MKL=ON \ -DWITH_MKL=ON \
-DWITH_MKLDNN=OFF \ -DWITH_MKLDNN=ON \
-DWITH_TESTING=OFF \ -DWITH_TESTING=OFF \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Release \
-DWITH_INFERENCE_API_TEST=OFF \ -DWITH_INFERENCE_API_TEST=OFF \
...@@ -132,6 +156,15 @@ inference/ ...@@ -132,6 +156,15 @@ inference/
sh tools/build.sh 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`的可执行文件。 * 编译完成之后,会在`build`文件夹下生成一个名为`ocr_system`的可执行文件。
......
...@@ -46,8 +46,6 @@ int main(int argc, char **argv) { ...@@ -46,8 +46,6 @@ int main(int argc, char **argv) {
std::string img_path(argv[2]); std::string img_path(argv[2]);
auto start = std::chrono::system_clock::now();
cv::Mat srcimg = cv::imread(img_path, cv::IMREAD_COLOR); cv::Mat srcimg = cv::imread(img_path, cv::IMREAD_COLOR);
DBDetector det(config.det_model_dir, config.use_gpu, config.gpu_id, DBDetector det(config.det_model_dir, config.use_gpu, config.gpu_id,
...@@ -59,6 +57,7 @@ int main(int argc, char **argv) { ...@@ -59,6 +57,7 @@ int main(int argc, char **argv) {
config.gpu_mem, config.cpu_math_library_num_threads, config.gpu_mem, config.cpu_math_library_num_threads,
config.char_list_file); config.char_list_file);
auto start = std::chrono::system_clock::now();
std::vector<std::vector<std::vector<int>>> boxes; std::vector<std::vector<std::vector<int>>> boxes;
det.Run(srcimg, boxes); det.Run(srcimg, boxes);
......
...@@ -12,22 +12,8 @@ ...@@ -12,22 +12,8 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // 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 <include/ocr_det.h>
#include <stdlib.h>
namespace PaddleOCR { namespace PaddleOCR {
......
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
namespace PaddleOCR { namespace PaddleOCR {
void PostProcessor::GetContourArea(float **box, float unclip_ratio, void PostProcessor::GetContourArea(const std::vector<std::vector<float>> &box,
float &distance) { float unclip_ratio, float &distance) {
int pts_num = 4; int pts_num = 4;
float area = 0.0f; float area = 0.0f;
float dist = 0.0f; float dist = 0.0f;
...@@ -34,7 +34,8 @@ void PostProcessor::GetContourArea(float **box, float unclip_ratio, ...@@ -34,7 +34,8 @@ void PostProcessor::GetContourArea(float **box, float unclip_ratio,
distance = area * unclip_ratio / dist; 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; float distance = 1.0;
GetContourArea(box, unclip_ratio, distance); GetContourArea(box, unclip_ratio, distance);
...@@ -74,53 +75,11 @@ float **PostProcessor::Mat2Vec(cv::Mat mat) { ...@@ -74,53 +75,11 @@ float **PostProcessor::Mat2Vec(cv::Mat mat) {
return array; 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>> 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; 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>> leftmost = {box[0], box[1]};
std::vector<std::vector<int>> rightmost = {box[2], box[3]}; std::vector<std::vector<int>> rightmost = {box[2], box[3]};
...@@ -135,16 +94,44 @@ PostProcessor::order_points_clockwise(std::vector<std::vector<int>> pts) { ...@@ -135,16 +94,44 @@ PostProcessor::order_points_clockwise(std::vector<std::vector<int>> pts) {
return rect; return rect;
} }
float **PostProcessor::GetMiniBoxes(cv::RotatedRect box, float &ssid) { std::vector<std::vector<float>> PostProcessor::Mat2Vector(cv::Mat mat) {
ssid = box.size.width >= box.size.height ? box.size.height : box.size.width; 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::Mat points;
cv::boxPoints(box, 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]) { if (array[3][1] <= array[2][1]) {
idx2 = array[3]; idx2 = array[3];
idx3 = array[2]; idx3 = array[2];
...@@ -168,7 +155,8 @@ float **PostProcessor::GetMiniBoxes(cv::RotatedRect box, float &ssid) { ...@@ -168,7 +155,8 @@ float **PostProcessor::GetMiniBoxes(cv::RotatedRect box, float &ssid) {
return array; 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; auto array = box_array;
int width = pred.cols; int width = pred.cols;
int height = pred.rows; int height = pred.rows;
...@@ -280,7 +268,7 @@ PostProcessor::FilterTagDetRes(std::vector<std::vector<std::vector<int>>> boxes, ...@@ -280,7 +268,7 @@ PostProcessor::FilterTagDetRes(std::vector<std::vector<std::vector<int>>> boxes,
std::vector<std::vector<std::vector<int>>> root_points; std::vector<std::vector<std::vector<int>>> root_points;
for (int n = 0; n < boxes.size(); n++) { 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++) { for (int m = 0; m < boxes[0].size(); m++) {
boxes[n][m][0] /= ratio_w; boxes[n][m][0] /= ratio_w;
boxes[n][m][1] /= ratio_h; boxes[n][m][1] /= ratio_h;
......
OPENCV_DIR=/paddle/libs/opencv-3.4.7/opencv3 OPENCV_DIR=your_opencv_dir
LIB_DIR=/paddle/code/gry/Paddle/build/fluid_inference_install_dir/ LIB_DIR=your_paddle_inference_dir
CUDA_LIB_DIR=/usr/local/cuda/lib64 CUDA_LIB_DIR=your_cuda_lib_dir
CUDNN_LIB_DIR=/usr/lib/x86_64-linux-gnu/ CUDNN_LIB_DIR=/your_cudnn_lib_dir
TENSORRT_ROOT_DIR=YOUR_TENSORRT_ROOT_DIR
BUILD_DIR=build BUILD_DIR=build
rm -rf ${BUILD_DIR} rm -rf ${BUILD_DIR}
...@@ -19,8 +18,5 @@ cmake .. \ ...@@ -19,8 +18,5 @@ cmake .. \
-DOPENCV_DIR=${OPENCV_DIR} \ -DOPENCV_DIR=${OPENCV_DIR} \
-DCUDNN_LIB=${CUDNN_LIB_DIR} \ -DCUDNN_LIB=${CUDNN_LIB_DIR} \
-DCUDA_LIB=${CUDA_LIB_DIR} \ -DCUDA_LIB=${CUDA_LIB_DIR} \
-DTENSORRT_ROOT=YOUR_TENSORRT_ROOT_DIR
make -j make -j
...@@ -13,7 +13,7 @@ det_model_dir ./inference/det_db ...@@ -13,7 +13,7 @@ det_model_dir ./inference/det_db
# rec config # rec config
rec_model_dir ./inference/rec_crnn 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 img_path ../../doc/imgs/11.jpg
# show the detection results # show the detection results
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册