所有文档

          EasyDL定制AI训练平台

          经典版物体检测LinuxSDK集成文档-C++

          简介

          本文档介绍EasyEdge/EasyDL的Linux CPP SDK的使用方法。

          • 网络类型支持: - 图像分类 - 物体检测 - 图像分割
          • 硬件支持:

            • CPU: aarch64 armv7hf
            • ASIC: Hisilicon NNIE1.1 on aarch64(Hi3559AV100/Hi3559CV100等)
            • ASIC: Hisilicon NNIE1.2 on armv7l(Hi3519AV100/Hi3559V200等)
            • Intel Movidius MyRIAD2 / MyRIAD X on x86_64
            • Intel Movidius MyRIAD2 / MyRIAD X on armv7l(树莓派3b+)
            • Intel Movidius MyRIAD2 / MyRIAD X on aarch64
            • 比特大陆 Bitmain SE50 (BM1684)
          • 操作系统支持:

            • Linux (Ubuntu, Centos, Debian等)
            • 海思HiLinux
            • 树莓派Raspbian

          性能数据参考设备端SDK简介。

          Release Notes

          时间 版本 说明
          2020.10.29 0.5.7 优化多线程预测细节
          2020.09.17 0.5.6 支持linux aarch64架构的硬件接入intel神经计算棒预测;支持比特大陆计算盒SE50 BM1684
          2020.08.11 0.5.5 支持树莓派接入intel神经计算棒预测
          2020.06.23 0.5.4 arm引擎升级
          2020.05.15 0.5.3 支持EasyDL 专业版新增模型 ;支持树莓派(armv7hf, aarch64)
          2020.04.16 0.5.2 Jetson系列SDK支持多线程infer
          2020.02.23 0.5.0 新增支持人脸口罩模型;Jetson SDK支持批量图片推理; ARM支持图像分割
          2020.01.16 0.4.7 上线海思NNIE1.2,支持EasyEdge以及EasyDL;ARM引擎升级;增加推荐阈值支持
          2019.12.26 0.4.6 海思NNIE支持EasyDL专业版
          2019.11.02 0.4.5 移除curl依赖;支持自动编译OpenCV;支持EasyDL 专业版 Yolov3; 支持EasyDL经典版高精度物体检测模型升级
          2019.10.25 0.4.4 ARM引擎升级,性能提升30%; 支持EasyDL专业版模型
          2019.09.23 0.4.3 增加海思NNIE加速芯片支持
          2019.08.30 0.4.2 ARM引擎升级;支持分类高性能与高精度模型
          2019.07.25 0.4.1 引擎升级,性能提升
          2019.06.11 0.3.3 paddle引擎升级;性能提升
          2019.05.16 0.3.2 新增armv7l支持
          2019.04.25 0.3.1 优化硬件支持
          2019.03.29 0.3.0 ARM64 支持;效果提升
          2019.02.20 0.2.1 paddle引擎支持;效果提升
          2018.11.30 0.1.0 第一版!

          快速开始

          SDK在以下环境中测试通过

          • aarch64(arm64), Ubuntu 16.04, gcc 5.3 (RK3399)
          • Hi3559AV100, aarch64, Ubuntu 16.04, gcc 5.3
          • Hi3519AV100, armv7l , HiLinux 4.9.37, (Hi3519AV100R001C02SPC020)
          • armv7hf, Raspbian, (Raspberry 3b)
          • aarch64, Raspbian, (Raspberry 4b)
          • armv7l, Raspbian, (Raspberry 3b+)
          • Bitmain se50 BM1684, Debian 9

          安装依赖

          依赖包括

          • cmake 3+
          • gcc 5.4 (需包含 GLIBCXX_3.4.22) ,gcc / glibc版本请以实际SDK ldd的结果为准
          • opencv3.4.5 (可选)
          • opencv4.2.0 (可选)
          • openvino 2020.1版本 (可选)

          依赖说明:树莓派

          树莓派Raspberry默认为armv7hf系统,使用SDK包中名称中包含armv7hf_ARM_的tar包。如果是aarch64系统,使用SDK包中名称中包含aarch64_ARM_的tar包。

          在安装前可通过以下命令查看是32位还是64位 :

          # 以下是32位的结果
          cat /proc/device-tree/model
          Raspberry Pi 3 Model B Plus Rev 1.3
          
          getconf LONG_BIT
          32
          
          uname -m
          armv7l

          依赖说明:Intel Movidius MyRIAD2 / MyRIAD X on armv7l(树莓派3b+)

          需要安装OpenVINO™ toolkit,参考openvino toolkit 文档安装 2020.1版本,只需要安装InferenceEngine部分

          依赖说明:Intel Movidius MyRIAD2 / MyRIAD X on Linux aarch64

          不用单独安装OpenVINO™ toolkit 预测引擎。 需要自行安装OpenCV4.2.0,并在使用SDK时指定4.2.0版本OpenCV的路径 OpenCV源码编译安装地址

          依赖说明:比特大陆SE计算盒

          需要安装BMNNSDK2.2,并在CMakeList.txt中指定SDK安装地址:

          # 这里修改并填入所使用的bmnnsdk路径
          set(EDGE_BMSDK_ROOT "{这里填写sdk路径}")

          依赖说明:海思开发板

          海思开发板需要根据海思SDK文档配置开运行环境和编译环境,SDK和opencv都需要在该编译环境中编译。 NNIE1.2用arm-himix200-linux交叉编译好的opencv,下载链接:https://pan.baidu.com/s/13QW0ReeWx4ZwgYg4lretyw 密码:yq0s。下载后修改SDK CMakesList.txt

          使用序列号激活

          在控制台获取的序列号请通过global_controller()->set_licence_key("")方法设置。

          具体请参考SDK自带的Demo.cpp文件的使用方法。

          测试Demo

          模型资源文件默认已经打包在开发者下载的SDK包中。

          Demo工程直接编译即可运行。

          请先将tar包整体拷贝到具体运行的设备中,再解压缩编译; 对于硬件使用为Intel Movidius MyRIAD2 / MyRIAD X on Linux aarch64的,在编译前指定4.2.0版本OpenCV的路径: export OpenCV_DIR={opencv_install_prefix}/lib/cmake/opencv4

          请在官网获取序列号,填写在demo.cpp

          编译运行:

          cd demo
          mkdir build && cd build
          cmake .. && make
          ./easyedge_demo {模型RES文件夹}  {测试图片路径}
          # 如果是NNIE引擎,使用sudo运行
          sudo ./easyedge_demo {模型RES文件夹}  {测试图片路径}

          如果希望SDK自动编译安装所需要的OpenCV库,修改cmake的optionEDGE_BUILD_OPENCVON即可。 SDK会自动从网络下载opencv源码,并编译需要的module、链接。注意,此功能必须需联网。

          cmake -DEDGE_BUILD_OPENCV=ON .. && make -j16

          若需自定义library search path或者gcc路径,修改CMakeList.txt即可。

          对于硬件使用为Intel Movidius MyRIAD2 / MyRIAD X on Linux aarch64的,如果要使用Intel Movidius MyRIAD X(比如英特尔2代神经计算棒),openvino预测引擎要找到设备需要执行以下命令:

          cp ${CPP_SDK_DIR}/openvino/97-myriad-usbboot.rules  /etc/udev/rules.d/
          sudo udevadm control --reload-rules
          sudo udevadm trigger
          sudo ldconfig

          demo运行效果:

           > ./easyedge_demo ../../../../RES 2.jpeg
          2019-02-13 16:46:12,659 INFO [EasyEdge] [easyedge.cpp:34] 140606189016192 Baidu EasyEdge Linux Development Kit 0.2.1(20190213)
          2019-02-13 16:46:14,083 INFO [EasyEdge] [paddlev2_edge_predictor.cpp:60] 140606189016192 Allocate graph success.
          2019-02-13 16:46:14,326 DEBUG [EasyEdge] [paddlev2_edge_predictor.cpp:143] 140606189016192 Inference costs 168 ms
          1, 1:txt_frame, p:0.994905 loc: 0.168161, 0.153654, 0.920856, 0.779621
          Done

          测试Demo HTTP 服务

          编译demo完成之后,会同时生成一个http服务 运行

          # ./easyedge_serving {res_dir} {serial_key} {host, default 0.0.0.0} {port, default 24401}
           ./easyedge_serving ../../../RES "1111-1111-1111-1111" 0.0.0.0  24401

          后,日志中会显示

          HTTP is now serving at 0.0.0.0:24401

          字样,此时,开发者可以打开浏览器,http://{设备ip}:24401,选择图片来进行测试。

          同时,可以调用HTTP接口来访问服务,具体参考下文接口说明。

          使用说明

          使用该方式,将运行库嵌入到开发者的程序当中。

          使用流程

          请优先参考Demo的使用流程。遇到错误,请优先参考文件中的注释解释,以及日志说明。

              // step 0: 设置序列号
              global_controller()->set_licence_key("set your license here");
          
              // step 1: 配置模型资源目录
              PaddleFluidConfig config;
              config.model_dir = {模型文件目录};
          
              // step 2: 创建并初始化Predictor;这这里选择合适的引擎
              auto predictor = global_controller()->CreateEdgePredictor(config);
          
              auto img = cv::imread({图片路径});
              // step 3: 预测图像
              std::vector<EdgeResultData> result2;
              predictor->infer(img, result2);

          对于口罩检测模型,将 PaddleFluidConfig config修改为PaddleMultiStageConfig config即可。

          口罩检测模型请注意输入图片中人脸大小建议保持在 88到9696像素之间,可根据场景远近程度缩放图片后再传入SDK。

          初始化

          • 接口
          auto predictor = global_controller()->CreateEdgePredictor(config);
          predictor->init();

          若返回非0,请查看输出日志排查错误原因。

          预测图像

          • 接口
           /**
            * @brief
            * 通用接口
            * @param image: must be BGR , HWC format (opencv default)
            * @param result
            * @return
            */
           virtual int infer(
                   cv::Mat& image, std::vector<EdgeResultData>& result
           ) = 0;

          图片的格式务必为opencv默认的BGR, HWC格式。

          • 返回格式

          EdgeResultData中可以获取对应的分类信息、位置信息。

          struct EdgeResultData {
              int index;  // 分类结果的index
              std::string label;  // 分类结果的label
              float prob;  // 置信度
          
              // 物体检测活图像分割时才有
              float x1, y1, x2, y2;  // (x1, y1): 左上角, (x2, y2): 右下角; 均为0~1的长宽比例值。
          
              // 图像分割时才有
              cv::Mat mask;  // 0, 1 的mask
              std::string mask_rle;  // Run Length Encoding,游程编码的mask
          };

          关于矩形坐标

          x1 * 图片宽度 = 检测框的左上角的横坐标

          y1 * 图片高度 = 检测框的左上角的纵坐标

          x2 * 图片宽度 = 检测框的右下角的横坐标

          y2 * 图片高度 = 检测框的右下角的纵坐标

          关于图像分割mask

          cv::Mat mask为图像掩码的二维数组
          {
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
          }
          其中1代表为目标区域,0代表非目标区域

          关于图像分割mask_rle

          该字段返回了mask的游程编码,解析方式可参考 http demo

          以上字段可以参考demo文件中使用opencv绘制的逻辑进行解析

          设置序列号

          请在网页控制台中申请序列号,并在init初始化前设置。 LinuxSDK 首次使用需联网授权。

          virtual int set_licence_key(const std::string& license) = 0;

          日志配置

          设置 EdgeLogConfig 的相关参数。具体含义参考文件中的注释说明。

          EdgeLogConfig log_config;
          log_config.enable_debug = true;
          global_controller()->set_log_config(log_config);

          http服务

          1. 开启http服务

          http服务的启动参考demo_serving.cpp文件。

           /**
               * @brief 开启一个简单的demo http服务。
               * 该方法会block直到收到sigint/sigterm。
               * http服务里,图片的解码运行在cpu之上,可能会降低推理速度。
               * @tparam ConfigT
               * @param config
               * @param host
               * @param port
               * @param service_id service_id  user parameter, uri '/get/service_id' will respond this value with 'text/plain'
               * @param instance_num 实例数量,根据内存/显存/时延要求调整
               * @return
               */
              template<typename ConfigT>
              int start_http_server(
                      const ConfigT &config,
                      const std::string &host,
                      int port,
                      const std::string &service_id,
                      int instance_num = 1);

          2. 请求http服务

          开发者可以打开浏览器,http://{设备ip}:24401,选择图片来进行测试。

          URL中的get参数:

          参数 说明 默认值
          threshold 阈值过滤, 0~1 如不提供,则会使用模型的推荐阈值

          HTTP POST Body即为图片的二进制内容(无需base64, 无需json)

          Python请求示例

          import requests
          
          with open('./1.jpg', 'rb') as f:
              img = f.read()
              result = requests.post(
          	    'http://127.0.0.1:24401/',
          	    params={'threshold': 0.1},
          	    data=img).json()

          Java请求示例

          http 返回数据

          字段 类型说明 其他
          error_code Number 0为成功,非0参考message获得具体错误信息
          results Array 内容为具体的识别结果。其中字段的具体含义请参考预测图像-返回格式一节
          cost_ms Number 预测耗时ms,不含网络交互时间

          返回示例

          {
              "cost_ms": 52,
              "error_code": 0,
              "results": [
                  {
                      "confidence": 0.94482421875,
                      "index": 1,
                      "label": "IronMan",
                      "x1": 0.059185408055782318,
                      "x2": 0.18795496225357056,
                      "y1": 0.14762254059314728,
                      "y2": 0.52510076761245728
                  },
                  {
                      "confidence": 0.94091796875,
                      "index": 1,
                      "label": "IronMan",
                      "x1": 0.79151463508605957,
                      "x2": 0.92310667037963867,
                      "y1": 0.045728668570518494,
                      "y2": 0.42920106649398804
                  }
                ]
          }

          其他配置

          1. 日志名称、HTTP 网页标题设置

          通过global_controller的set_config方法设置:

          global_controller()->set_config(easyedge::params::KEY_LOG_BRAND, "MY_BRAND");

          效果如下: 图片

          FAQ

          1. 如何处理一些 undefined reference?

          如:undefined reference to `curl_easy_setopt@CURL_OPENSSL_3'

          方案1:通过安装libcurl3 libcurl-openssl1.0-dev来解决。 方案2:如果开发者想不想使用低版本的openssl(如Ubuntu 18.04), 可以link静态库easyedge_static.a,自己指定需要的Library的版本:

          示例:修改CMakeList.txt

          find_package(CURL REQUIRED)
          target_link_libraries(easyedge_demo  ${OpenCV_LIBS} easyedge_static pthread ${CURL_LIBRARIES} verify_static ${其他需要的库})

          其中, 其他需要的库视具体sdk中包含的库而定。

          2. EasyDL SDK与云服务效果不一致,如何处理?

          后续我们会消除这部分差异,如果开发者发现差异较大,可联系我们协助处理。

          3. 如何将我的模型运行为一个http服务?

          目前cpp sdk暂未集成http运行方式; 0.4.7版本之后,可以通过start_http_server方法开启http服务。

          4. 运行NNIE引擎报permission denied

          日志显示:

          open sys: Permission denied
          open err
          : Permission denied
          open err
          : Permission denied

          请使用sudo在root下运行。

          5. 运行SDK报错 Authorization failed

          日志显示 Http perform failed: null respond 在新的硬件上首次运行,必须联网激活。

          SDK 能够接受HTTP_PROXY 的环境变量通过代理处理自己的网络请求。如

          export HTTP_PROXY="http://192.168.1.100:8888"
          ./easyedge_demo ...

          6. 使用libcurl请求http服务时,速度明显变慢

          这是因为libcurl请求continue导致server等待数据的问题,添加空的header即可

          headers = curl_slist_append(headers, "Expect:");

          7. 运行NNIE引擎报错 std::bad_alloc

          检查开发板可用内存,一些比较大的网络占用内存较多,推荐内存500M以上

          8. 运行二进制时,提示 libverify.so cannot open shared object file

          可能cmake没有正确设置rpath, 可以设置LD_LIBRARY_PATH为sdk的lib文件夹后,再运行:

          LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../lib ./easyedge_demo

          9. 编译时报错:file format not recognized

          可能是因为在复制SDK时文件信息丢失。请将整个压缩包复制到目标设备中,再解压缩、编译

          上一篇
          LinuxSDK集成文档-Python
          下一篇
          Linux(Atlas)SDK集成文档