C++示例
示例目录结构
edgeboard-191:~/root/workspace/PaddleLiteDemo# ls
C++ README.md configs python res
C++
: C++语言编写的demo 源码
python
: python语言编写的demo 源码
configs
: 存放了示例运行需要的配置文件
res
: 存放了模型相关文件和图片文件
系统配置文件描述
configs目录中已经默认添加每个 模型对应4种不同 输入源的配置
configs ✗ tree
.
├── classification
│ ├── Inceptionv2
│ ├── Inceptionv3
│ ├── mobilenetv1
│ └── resnet50
│ ├── image.json
│ ├── multi_channel_camera.json
│ ├── rtspcamera.json
│ └── usbcamera.json
├── detection
│ ├── mobilenet-ssd
│ ├── mobilenet-ssd-640
│ ├── mobilenet-yolov3
│ ├── vgg-ssd
│ └── yolov3
│ ├── image.json
│ ├── multi_channel_camera.json
│ ├── rtspcamera.json
│ └── usb_camera.json
└── segmentation
└── deeplabv3
├── image.json
├── multi_channel_camera.json
├── rtspcamera.json
└── usbcamera.json
13 directories, 12 files
json配置文件格式如下:
{
"model_config": "../../res/modles/detection/yolov3",
"input": {
"type": "usb_camera",
"path": "/dev/video2"
},
"debug": {
"display_enable": true,
"predict_log_enable": true,
"predict_time_log_enable": true
}
}
配置文件参数说明:
model_config
: 模型的目录,相对于 PaddleLiteDemo/C++/build
目录,各个示例支持的模型见目录
type
: 输入源的类型,可选项目,支持的value有:image、usb_camera、rtsp_camera、multichannel_camera
path
: 输入源对应的 设备节点或url 或 图片的名字
type | path | 备注 | 支持的设备 |
---|---|---|---|
image | ../../res/models/XXX | 使用图片作为输入源 | ALL |
usb_camera | /dev/video0 | USB摄像头 | FZ3X/5X |
usb_camera | /dev/video2 | USB摄像头 | FZ9D |
rtsp_camera | rtsp://admin:eb123456@192.168.1.167/ | RTSP摄像头 | FZ5X |
multichannel_camera | /dev/video1 | 多路分时复用摄像头 | FZ9D |
注意: 只有FZ9D 支持 multichannel_camera
display_enable
: 显示器显示开关,当没有显示器时可以设置为 false
predict_log_enable
: 预测的结果通过命令行打印的开关
predict_time_log_enable
: 模型预测单帧耗时的打印开关(不包括图像处理时间)
模型配置文件描述
模型配置文件位于res/model
每个模型文件夹下
{
"network_type":"YOLOV3",
"model_file_name":"model",
"params_file_name":"params",
"labels_file_name":"label_list.txt",
"format":"RGB",
"input_width":608,
"input_height":608,
"mean":[123.675, 116.28, 103.53],
"scale":[0.0171248, 0.017507, 0.0174292],
"threshold":0.3
}
参数说明:
模型类型:
- 非融合模型:
model_file_name
: 指定模型文件的名字
params_file_name
: 指定模型参数文件的名字
- 融合模型:
model_dir
: 指定 模型与参数的目录
C++示例运行
编译
cd PaddleLiteDemo/C++
mkdir build
cd build
cmake ..
make
结果产生3个可执行文件:
classification
: 分类示例
detection
: 检测示例
segmentation
: 分割示例
执行
默认使用 configs
目录下的image.json, 通过配置文件可以切换 模型 和 输入源等,
执行默认配置
# 执行分类模型默认配置
./classification
# 执行检测模型默认配置
./detection
# 执行分割模型默认配置
./segmentation
执行指定配置
如: 检测示例yolov3 ,用usbcamera 的方法:
./detection ../../configs/detection/yolov3/usb_camera.json
注意:camera 类型的输入需要接入显示器,需要将显示器设置为 720P,设置方式
startx #开启显示器桌面
xrandr -s 1280x720 #设置显示器分辨率为720p
C++接口调用
具体详情请查看PaddleLite API文档 C++接口文档
C++ API
CreatePaddlePredictor
template <typename ConfigT>
std::shared_ptr<PaddlePredictor> CreatePaddlePredictor(const ConfigT&);
CreatePaddlePredictor用来根据CxxConfig构建预测器。
示例:
CxxConfig
class CxxConfig;
CxxConfig用来配置构建CxxPredictor的配置信息,如protobuf格式的模型地址、能耗模式、工作线程数、place信息等等。
示例:
//构造places, FPGA使用以下几个places。
std::vector<Place> valid_places({
Place{TARGET(kFPGA), PRECISION(kFP16), DATALAYOUT(kNHWC)},
Place{TARGET(kHost), PRECISION(kFloat)},
Place{TARGET(kARM), PRECISION(kFloat)},
});
//构造模型加载参数
paddle::lite_api::CxxConfig config;
std::string model = value["model"];
bool combined = true;
std::string model_dir = model;
if (combined) {
//设置组合模型路径(两个文件)
config.set_model_file(model_dir + "/model");
config.set_param_file(model_dir + "/params");
} else {
//设置模型目录路径,适用于一堆文件的模型
config.set_model_dir(model_dir);
}
config.set_valid_places(valid_places);
// 创建PaddleLite实例
auto predictor = paddle::lite_api::CreatePaddlePredictor(config);
PaddlePredictor
PaddlePredictor是Paddle-Lite的预测器,由CreatePaddlePredictor根据CxxConfig进行创建。用户可以根据PaddlePredictor提供的接口设置输入数据、执行模型预测、获取输出以及获得当前使用lib的版本信息等。
//获取第0个输入tensor,有多个输入时,可根据相应下标获取
auto input = predictor->GetInput(0);
//调整输入大小
input->Resize({1, 3, height, width});
//获取tensor数据指针
auto* in_data = input->mutable_data<float>();
//图片读入相应数组当中
read_image(value, in_data);
//推理
predictor->Run();
//获取结果tensor,有多个结果时,可根据相应下标获取
auto output = predictor->GetOutput(0);
//获取结果数据
float *data = output->mutable_data<float>();
Tensor
Tensor是Paddle-Lite的数据组织形式,用于对底层数据进行封装并提供接口对数据进行操作,包括设置Shape、数据、LoD信息等。
注意:用户应使用PaddlePredictor的GetInput和GetOuput接口获取输入/输出的Tensor。
// 通过调用Resize调整Tensor纬度
input->Resize({1, 3, height, width})
//通过SetLoD设置lod信息。
input->SetLod(lod);
//-----------------------------------------
// 获取数出tensor
auto output = predictor->GetOutput(0);
//获取结果数据
float *data = output->mutable_data<float>();
//tensor->shape()返回Tensor维度信息。
int size = output->shape()[0];