cpp shitu code format

pull/1437/head
dongshuilong 2021-11-15 12:19:21 +08:00
parent a96305c225
commit 29f8fb830a
19 changed files with 1314 additions and 1291 deletions

View File

@ -59,9 +59,7 @@ public:
this->resize_size_ = this->resize_size_ =
config_file["RecPreProcess"]["transform_ops"][0]["ResizeImage"]["size"] config_file["RecPreProcess"]["transform_ops"][0]["ResizeImage"]["size"]
.as<int>(); .as<int>();
this->scale_ = config_file["RecPreProcess"]["transform_ops"][1] this->scale_ = config_file["RecPreProcess"]["transform_ops"][1]["NormalizeImage"]["scale"].as<float>();
["NormalizeImage"]["scale"]
.as<float>();
this->mean_ = config_file["RecPreProcess"]["transform_ops"][1] this->mean_ = config_file["RecPreProcess"]["transform_ops"][1]
["NormalizeImage"]["mean"] ["NormalizeImage"]["mean"]
.as < std::vector < float >> (); .as < std::vector < float >> ();
@ -81,6 +79,7 @@ public:
// Run predictor // Run predictor
void Run(cv::Mat &img, std::vector<float> &out_data, void Run(cv::Mat &img, std::vector<float> &out_data,
std::vector<double> &times); std::vector<double> &times);
void FeatureNorm(std::vector<float> &feature); void FeatureNorm(std::vector<float> &feature);
std::shared_ptr <Predictor> predictor_; std::shared_ptr <Predictor> predictor_;

View File

@ -88,9 +88,11 @@ public:
std::vector <ObjectResult> *result = nullptr, std::vector <ObjectResult> *result = nullptr,
std::vector<int> *bbox_num = nullptr, std::vector<int> *bbox_num = nullptr,
std::vector<double> *times = nullptr); std::vector<double> *times = nullptr);
const std::vector <std::string> &GetLabelList() const { const std::vector <std::string> &GetLabelList() const {
return this->label_list_; return this->label_list_;
} }
const float &GetThreshold() const { return this->threshold_; } const float &GetThreshold() const { return this->threshold_; }
private: private:
@ -120,6 +122,7 @@ private:
// Preprocess image and copy data to input buffer // Preprocess image and copy data to input buffer
void Preprocess(const cv::Mat &image_mat); void Preprocess(const cv::Mat &image_mat);
// Postprocess result // Postprocess result
void Postprocess(const std::vector <cv::Mat> mats, void Postprocess(const std::vector <cv::Mat> mats,
std::vector <ObjectResult> *result, std::vector<int> bbox_num, std::vector <ObjectResult> *result, std::vector<int> bbox_num,

View File

@ -49,12 +49,14 @@ public:
class PreprocessOp { class PreprocessOp {
public: public:
virtual void Init(const YAML::Node &item) = 0; virtual void Init(const YAML::Node &item) = 0;
virtual void Run(cv::Mat *im, ImageBlob *data) = 0; virtual void Run(cv::Mat *im, ImageBlob *data) = 0;
}; };
class InitInfo : public PreprocessOp { class InitInfo : public PreprocessOp {
public: public:
virtual void Init(const YAML::Node &item) {} virtual void Init(const YAML::Node &item) {}
virtual void Run(cv::Mat *im, ImageBlob *data); virtual void Run(cv::Mat *im, ImageBlob *data);
}; };
@ -78,6 +80,7 @@ private:
class Permute : public PreprocessOp { class Permute : public PreprocessOp {
public: public:
virtual void Init(const YAML::Node &item) {} virtual void Init(const YAML::Node &item) {}
virtual void Run(cv::Mat *im, ImageBlob *data); virtual void Run(cv::Mat *im, ImageBlob *data);
}; };

View File

@ -46,10 +46,15 @@ public:
this->I.resize(this->return_k * this->max_query_number); this->I.resize(this->return_k * this->max_query_number);
this->D.resize(this->return_k * this->max_query_number); this->D.resize(this->return_k * this->max_query_number);
}; };
void LoadIdMap(); void LoadIdMap();
void LoadIndexFile(); void LoadIndexFile();
const SearchResult &Search(float *feature, int query_number); const SearchResult &Search(float *feature, int query_number);
const std::string &GetLabel(faiss::Index::idx_t ind); const std::string &GetLabel(faiss::Index::idx_t ind);
const float &GetThreshold() { return this->score_thres; } const float &GetThreshold() { return this->score_thres; }
private: private:

View File

@ -45,9 +45,14 @@ public:
explicit YamlConfig(const std::string &path) { explicit YamlConfig(const std::string &path) {
config_file = ReadYamlConfig(path); config_file = ReadYamlConfig(path);
} }
static std::vector <std::string> ReadDict(const std::string &path); static std::vector <std::string> ReadDict(const std::string &path);
static std::map<int, std::string> ReadIndexId(const std::string &path); static std::map<int, std::string> ReadIndexId(const std::string &path);
static YAML::Node ReadYamlConfig(const std::string &path); static YAML::Node ReadYamlConfig(const std::string &path);
void PrintConfigInfo(); void PrintConfigInfo();
YAML::Node config_file; YAML::Node config_file;
}; };

View File

@ -6,10 +6,7 @@
## 1. 准备环境 ## 1. 准备环境
### 运行准备 ### 运行准备
- Linux环境推荐使用docker。 - Linux环境推荐使用ubuntu docker。
- Windows环境目前支持基于`Visual Studio 2019 Community`进行编译;此外,如果您希望通过生成`sln解决方案`的方式进行编译,可以参考该文档:[https://zhuanlan.zhihu.com/p/145446681](https://zhuanlan.zhihu.com/p/145446681)
* 该文档主要介绍基于Linux环境下的PaddleClas C++预测流程如果需要在Windows环境下使用预测库进行C++预测,具体编译方法请参考[Windows下编译教程](./docs/windows_vs2019_build.md)。
### 1.1 编译opencv库 ### 1.1 编译opencv库
@ -103,7 +100,7 @@ make -j
make inference_lib_dist make inference_lib_dist
``` ```
更多编译参数选项可以参考Paddle C++预测库官网[https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/guides/05_inference_deployment/inference/build_and_install_lib_cn.html#id16](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/guides/05_inference_deployment/inference/build_and_install_lib_cn.html#id16)。 更多编译参数选项可以参考[Paddle C++预测库官网](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/guides/05_inference_deployment/inference/build_and_install_lib_cn.html#id16)。
* 编译完成之后,可以在`build/paddle_inference_install_dir/`文件下看到生成了以下文件及文件夹。 * 编译完成之后,可以在`build/paddle_inference_install_dir/`文件下看到生成了以下文件及文件夹。
@ -137,6 +134,7 @@ tar -xvf paddle_inference.tgz
### 1.3 安装faiss库 ### 1.3 安装faiss库
```shell ```shell
# 下载 faiss
git clone https://github.com/facebookresearch/faiss.git git clone https://github.com/facebookresearch/faiss.git
cd faiss cd faiss
cmake -B build . -DFAISS_ENABLE_PYTHON=OFF -DCMAKE_INSTALL_PREFIX=${faiss_install_path} cmake -B build . -DFAISS_ENABLE_PYTHON=OFF -DCMAKE_INSTALL_PREFIX=${faiss_install_path}
@ -144,22 +142,19 @@ tar -xvf paddle_inference.tgz
make -C build install make -C build install
``` ```
## 2 开始运行 在安装`faiss`前,请安装`openblas``ubuntu`系统中安装命令如下:
### 2.1 将模型导出为inference model
* 可以参考[模型导出](../../tools/export_model.py),导出`inference model`,用于模型预测。得到预测模型后,假设模型文件放在`inference`目录下,则目录结构如下。
```shell
apt-get install libopenblas-dev
``` ```
inference/
|--cls_infer.pdmodel 注意本教程以安装faiss cpu版本为例安装时请参考[faiss](https://github.com/facebookresearch/faiss)官网文档,根据需求自行安装。
|--cls_infer.pdiparams
``` ## 2 代码编译
**注意**:上述文件中,`cls_infer.pdmodel`文件存储了模型结构信息,`cls_infer.pdiparams`文件存储了模型参数信息。注意两个文件的路径需要与配置文件`tools/config.txt`中的`cls_model_path`和`cls_params_path`参数对应一致。
### 2.2 编译PaddleClas C++预测demo ### 2.2 编译PaddleClas C++预测demo
* 编译命令如下其中Paddle C++预测库、opencv等其他依赖库的地址需要换成自己机器上的实际地址。 编译命令如下其中Paddle C++预测库、opencv等其他依赖库的地址需要换成自己机器上的实际地址。同时,编译过程中需要下载编译`yaml-cpp`等C++库,请保持联网环境。
```shell ```shell
@ -169,11 +164,12 @@ sh tools/build.sh
具体地,`tools/build.sh`中内容如下。 具体地,`tools/build.sh`中内容如下。
```shell ```shell
OPENCV_DIR=your_opencv_dir OPENCV_DIR=${opencv_install_dir}
LIB_DIR=your_paddle_inference_dir LIB_DIR=${paddle_inference_dir}
CUDA_LIB_DIR=your_cuda_lib_dir CUDA_LIB_DIR=/usr/local/cuda/lib64
CUDNN_LIB_DIR=your_cudnn_lib_dir CUDNN_LIB_DIR=/usr/lib/x86_64-linux-gnu/
TENSORRT_DIR=your_tensorrt_lib_dir FAISS_DIR=${faiss_install_dir}
FAISS_WITH_MKL=OFF
BUILD_DIR=build BUILD_DIR=build
rm -rf ${BUILD_DIR} rm -rf ${BUILD_DIR}
@ -182,14 +178,14 @@ cd ${BUILD_DIR}
cmake .. \ cmake .. \
-DPADDLE_LIB=${LIB_DIR} \ -DPADDLE_LIB=${LIB_DIR} \
-DWITH_MKL=ON \ -DWITH_MKL=ON \
-DDEMO_NAME=clas_system \
-DWITH_GPU=OFF \ -DWITH_GPU=OFF \
-DWITH_STATIC_LIB=OFF \ -DWITH_STATIC_LIB=OFF \
-DWITH_TENSORRT=OFF \ -DUSE_TENSORRT=OFF \
-DTENSORRT_DIR=${TENSORRT_DIR} \
-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} \
-DFAISS_DIR=${FAISS_DIR} \
-DFAISS_WITH_MKL=${FAISS_WITH_MKL}
make -j make -j
``` ```
@ -197,47 +193,75 @@ make -j
上述命令中, 上述命令中,
* `OPENCV_DIR`为opencv编译安装的地址本例中为`opencv-3.4.7/opencv3`文件夹的路径); * `OPENCV_DIR`为opencv编译安装的地址本例中为`opencv-3.4.7/opencv3`文件夹的路径);
* `LIB_DIR`为下载的Paddle预测库`paddle_inference`文件夹或编译生成的Paddle预测库`build/paddle_inference_install_dir`文件夹)的路径; * `LIB_DIR`为下载的Paddle预测库`paddle_inference`文件夹或编译生成的Paddle预测库`build/paddle_inference_install_dir`文件夹)的路径;
* `CUDA_LIB_DIR`为cuda库文件地址在docker中为`/usr/local/cuda/lib64` * `CUDA_LIB_DIR`为cuda库文件地址在docker中为`/usr/local/cuda/lib64`
* `CUDNN_LIB_DIR`为cudnn库文件地址在docker中为`/usr/lib/x86_64-linux-gnu/`。 * `CUDNN_LIB_DIR`为cudnn库文件地址在docker中为`/usr/lib/x86_64-linux-gnu/`。
* `TENSORRT_DIR`是tensorrt库文件地址在dokcer中为`/usr/local/TensorRT6-cuda10.0-cudnn7/`TensorRT需要结合GPU使用。 * `TENSORRT_DIR`是tensorrt库文件地址在dokcer中为`/usr/local/TensorRT6-cuda10.0-cudnn7/`TensorRT需要结合GPU使用。
* `FAISS_DIR`是faiss的安装地址
在执行上述命令,编译完成之后,会在当前路径下生成`build`文件夹,其中生成一个名为`clas_system`的可执行文件。 * `FAISS_WITH_MKL`是指在编译faiss的过程中是否使用了mkldnn本文档中编译faiss没有使用而使用了openblas故设置为`OFF`若使用了mkldnn则为`ON`.
### 运行demo 在执行上述命令,编译完成之后,会在当前路径下生成`build`文件夹,其中生成一个名为`pp_shitu`的可执行文件。
* 首先修改`tools/config.txt`中对应字段:
* use_gpu是否使用GPU
* gpu_id使用的GPU卡号
* gpu_mem显存
* cpu_math_library_num_threads底层科学计算库所用线程的数量
* use_mkldnn是否使用MKLDNN加速
* use_tensorrt: 是否使用tensorRT进行加速
* use_fp16是否使用半精度浮点数进行计算该选项仅在use_tensorrt为true时有效
* cls_model_path预测模型结构文件路径
* cls_params_path预测模型参数文件路径
* resize_short_size预处理时图像缩放大小
* crop_size预处理时图像裁剪后的大小。
* 然后修改`tools/run.sh` ## 3 运行demo
* `./build/clas_system ./tools/config.txt ./docs/imgs/ILSVRC2012_val_00000666.JPEG`
* 上述命令中分别为:编译得到的可执行文件`clas_system`;运行时的配置文件`config.txt`;待预测的图像。
* 最后执行以下命令,完成对一幅图像的分类 - 请参考[识别快速开始文档](../../docs/zh_CN/quick_start/quick_start_recognition.md),下载好相应的 轻量级通用主体检测模型、轻量级通用识别模型及瓶装饮料测试数据并解压。
```shell ```shell
sh tools/run.sh mkdir models
cd models
wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/picodet_PPLCNet_x2_5_mainbody_lite_v1.0_infer.tar
tar -xf picodet_PPLCNet_x2_5_mainbody_lite_v1.0_infer.tar
wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/general_PPLCNet_x2_5_lite_v1.0_infer.tar
tar -xf general_PPLCNet_x2_5_lite_v1.0_infer.tar
cd ..
mkdir data
cd data
wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/data/drink_dataset_v1.0.tar
tar -xf drink_dataset_v1.0.tar
cd ..
``` ```
* 最终屏幕上会输出结果,如下图所示。 - 将相应的yaml文件拷到`test`文件夹下
<div align="center"> ```shell
<img src="./docs/imgs/cpp_infer_result.png" width="600"> cp ../configs/inference_drink.yaml .
</div> ```
- 将`inference_drink.yaml`中的相对路径,改成基于本目录的路径或者绝对路径。涉及到的参数有
其中`class id`表示置信度最高的类别对应的idscore表示图片属于该类别的概率。 - Global.infer_imgs :此参数可以是具体的图像地址,也可以是图像集所在的目录
- Global.det_inference_model_dir 检测模型存储目录
- Global.rec_inference_model_dir 识别模型存储目录
- IndexProcess.index_dir 检索库的存储目录在示例中检索库在下载的demo数据中。
- 字典转换
由于python的检索库的字典使用`pickle`进行的序列化存储导致C++不方便读取,因此进行转换
```shell
python tools/transform_id_map.py -c inference_drink.yaml
```
转换成功后,在`IndexProcess.index_dir`目录下生成`id_map.txt`方便c++ 读取。
- 执行程序
```shell
./build/pp_shitu -c inference_drink.yaml
# or
./build/pp_shitu -config inference_drink.yaml
```
若对图像集进行检索,则可能得到,如下结果。注意,此结果只做展示,具体以实际运行结果为准。
同时需注意的是由于opencv 版本问题会导致图像在预处理的过程中resize产生细微差别导致python 和c++结果轻微不同如bbox相差几个像素检索结果小数点后3位diff等。但不会改变最终检索label。
![](../../docs/images/quick_start/shitu_c++_result.png)
## 4 使用自己模型
使用自己训练的模型,可以参考[模型导出](../../docs/zh_CN/inference_deployment/export_model.md),导出`inference model`,用于模型预测。
同时注意修改`yaml`文件中具体参数。

View File

@ -37,8 +37,10 @@
using namespace std; using namespace std;
using namespace cv; using namespace cv;
DEFINE_string(config, "", "Path of yaml file"); DEFINE_string(config,
DEFINE_string(c, "", "Path of yaml file"); "", "Path of yaml file");
DEFINE_string(c,
"", "Path of yaml file");
void DetPredictImage(const std::vector <cv::Mat> &batch_imgs, void DetPredictImage(const std::vector <cv::Mat> &batch_imgs,
const std::vector <std::string> &all_img_paths, const std::vector <std::string> &all_img_paths,

View File

@ -1,8 +1,8 @@
OPENCV_DIR=/work/project/project/cpp_infer/opencv-3.4.7/opencv3 OPENCV_DIR=${opencv_install_dir}
LIB_DIR=/work/project/project/cpp_infer/paddle_inference/ LIB_DIR=${paddle_inference_dir}
CUDA_LIB_DIR=/usr/local/cuda/lib64 CUDA_LIB_DIR=/usr/local/cuda/lib64
CUDNN_LIB_DIR=/usr/lib/x86_64-linux-gnu/ CUDNN_LIB_DIR=/usr/lib/x86_64-linux-gnu/
FAISS_DIR=/work/project/project/cpp_infer/faiss/faiss_install FAISS_DIR=${faiss_install_dir}
FAISS_WITH_MKL=OFF FAISS_WITH_MKL=OFF
BUILD_DIR=build BUILD_DIR=build

View File

@ -1,17 +0,0 @@
# model load config
use_gpu 0
gpu_id 0
gpu_mem 4000
cpu_threads 10
use_mkldnn 1
use_tensorrt 0
use_fp16 0
# cls config
cls_model_path /PaddleClas/inference/cls_infer.pdmodel
cls_params_path /PaddleClas/inference/cls_infer.pdiparams
resize_short_size 256
crop_size 224
# for log env info
benchmark 0

View File

@ -1 +0,0 @@
./build/clas_system ../configs/inference_rec.yaml

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB