• linux paddle For C++环境搭建


    paddle介绍

    Paddle是类似tesseract的文字识别ocr。因为tesseract-ocr的中文识别效果不好。因此才准备安装Paddle。Paddle最方便的安装方式的使用Python的包管理安装。pip3 install paddlepaddle。但我使用了一下感觉还是用C++更加方便,QT + OpenCV + Paddle应当还不错。所以才有了下面这一篇教程。

    环境说明

    1. 电脑系统是Ubuntu23.04
    2. 安装的OpenCV是使用apt安装的,不是自己编译安装的
    3. 因为墙的原因,直接使用的Paddle编译好的库,没有使用源码安装

    安装步骤

    1. 确保系统中已经安装openCV
    # 搜索安装opencv
    sudo apt search libopencv-dev
    sudo apt install libopencv-dev
    # 确定pkg-config能找到opencv头文件和库文件
    pkg-config --libs --cflags opencv4
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. 下载Paddle库文件

    这里下载。我下载的是manylinux_cpu_avx_mkl_gcc8.2
    下载完成后解压。

    tar zxvf paddle_inference.tgz
    cd paddle_inference/
    # 这个目录中就是paddle的头文件和相关库文件
    # 这里的库文件需要提取出来,加入到系统搜索目录
    # 使用下面的命令提取出共享库文件
    mkdir paddle_lib
    find . -name "*.so*" | xargs -i cp {} ./paddle_lib
    # 完成后paddle_lib目录下面就会有几个动态库文件
    # 下面将这些动态库加入到系统搜索目录中
    cp -a paddle_lib /usr/lib
    vi /etc/ld.so.conf.d/paddle.conf
    # 加入搜索目录
    /usr/lib/paddle_lib
    # 更新
    ldconfig
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1. 下载推理模型model和PaddleOCR

    PaddleOCR类似一个Paddle的命令行命令,但这个命令需要自己编译,不像tesseract可以直接使用apt安装。这里编译PaddleOCR是从源码编译的有点麻烦,如果只是想在C++中使用Paddle可以不用编译PaddleOCR,但了解如何编译PaddleOCR可以帮助您理解paddle的编译过程。

    # 使用下面命令下载PaddleOCR
    git clone https://gitee.com/paddlepaddle/PaddleOCR.git
    
    • 1
    • 2

    这里下载推理模型。下载时点击"推理模型"链接下载,我下载的是ch_ppocr_server_v2.0_det_infer.tar,49.5M。下载后解压。
    将解压后的文件放到PaddleOCR/PaddleOCR/deploy/cpp_infer/inference。这里的inference目录是自己新建的,用于存放模型文件。

    cd PaddleOCR/deploy/cpp_infer/
    mkdir inference
    cd inference
    mv ~/Downloads/ch_ppocr_server_v2.0_det_infer .
    
    • 1
    • 2
    • 3
    • 4

    编译PaddleOCR

    编译之前需要修改一些配置

    cd PaddleOCR/deploy/cpp_infer/
    git checkout release/2.7
    vi tools/build.sh
    
    # 这里的你的opencv目录,因为我使用的apt安装的,试了几次指定opencv目录都无效
    # 因为这里设置失败,所以后面我直接更改的CMakeLists.txt
    OPENCV_DIR= "你的opencv安装目录"
    # 下面这个就是上面下载的Paddle库文件目录
    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}
    mkdir ${BUILD_DIR}
    cd ${BUILD_DIR}
    cmake .. \
        -DPADDLE_LIB=${LIB_DIR} \
        -DWITH_MKL=ON \
        -DWITH_GPU=OFF \
        -DWITH_STATIC_LIB=OFF \
        -DWITH_TENSORRT=OFF \
        -DOPENCV_DIR=${OPENCV_DIR} \
    #    -DCUDNN_LIB=${CUDNN_LIB_DIR} \
    #    -DCUDA_LIB=${CUDA_LIB_DIR} \
    #    -DTENSORRT_DIR=${TENSORRT_DIR} \
    
    # 根据你cpu核心数加个数字,多线编译
    make -j16
    
    # 再更改一下CMakeLists.txt第74行,这里的优化等级有问题。将-o3改为-O3
    vi CMakeLists.txt
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O3 ${FLAG_OPENMP} -std=    c++11")
    
    # 改了上面配置后就可以尝试编译一下了
    sh tools/build.sh
    
    # 如果你也和我一样找不到OpenCVConfig.cmake,可以像我一样直接更改CMakeLists.txt,不用cmake自带的find_package找opencv。我也试过更改CMAKE_PREFIX_PATH,明明目录下有OpenCVConfig.cmake,还是提示找不到OpenCVConfig.cmake。因此一气之下自己改CMakeLists.txt。如果找不到OpenCV会提示以下错误:
    CMake Error at CMakeLists.txt:47 (find_package):
      Could not find a package configuration file provided by "OpenCV" with any
      of the following names:
    
        OpenCVConfig.cmake
        opencv-config.cmake
    
      Add the installation prefix of "OpenCV" to CMAKE_PREFIX_PATH or set
      "OpenCV_DIR" to a directory containing one of the above files.  If "OpenCV"
      provides a separate development package or SDK, be sure it has been
      installed.
    
    # 可以更改CMakeLists.txt 49行,改为如下内容
    else ()
      #find_package(OpenCV REQUIRED PATHS ${OPENCV_DIR}/share/OpenCV NO_DEFAULT_PATH)
      find_package(PkgConfig)
      pkg_search_module(OPENCV4 REQUIRED opencv4)
      link_directories(${OPENCV4_LIBRARY_DIRS})
      link_libraries(${OPENCV4_LIBRARIES})
      include_directories(${OPENCV4_INCLUDE_DIRS})
      include_directories("${PADDLE_LIB}/paddle/include")
      link_directories("${PADDLE_LIB}/paddle/lib")
    endif ()
    #include_directories(${OpenCV_INCLUDE_DIRS})
    
    # 再尝试编译
    sh tools/build.sh
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    运行PaddleOCR

    ./ppocr --help
    # 如果不报错,而是显示支持的选项就表示成功了,PaddleOCR的命令就可以使用的
    # 只是一个帮助命令完全看不出推理有什么效果因此可以使用下面命令,看下推理效果
    ./build/ppocr --det_model_dir=../inference/ch_ppocr_server_v2.0_det_infer/ --image_dir=./doc/imgs/cmake_step3.png --det=true --rec=false
    # 如果报找不到图片,可以使用绝对路径
    # 运行成功后会在output目录下生成一个cmake_step3.png的图片,这个图片中的文字都会框出来
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    输入图片

    输出图片

    C++中使用paddle

    这里主要依照官网的教程,Paddle官网教程

    1. 确定已经下载Paddle库,并解压
    2. 这里下载ResNet50推理模型
    3. 下载推理示例
    git clone https://gitee.com/cuizhi/Paddle-Inference-Demo.git
    # 将步骤1下载的Paddle库,复制到Paddle-Inference-Demo/c++/lib/
    cp -a ~/Downloads/paddle_inference/ Paddle-Inference-Demo/c++/lib/
    # 将步骤2下载的推理模型复制到Paddle-Inference-Demo/c++/cpu/resnet50
    cp -a ~/Downloads/resnet50 Paddle-Inference-Demo/c++/cpu/resnet50
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. 修改编译选项
    # 因为我的电脑没有安装CUDA,因此需要关闭GPU选项
    cd Paddle-Inference-Demo/c++/cpu/resnet50
    vi complie.sh
    # 26行开始关闭ONNXRUNTIME,这个第三方库老是与库里要求版本不一致
    WITH_MKL=ON
    WITH_ONNXRUNTIME=OFF
    WITH_ARM=OFF
    WITH_MIPS=OFF
    WITH_SW=OFF
    
    LIB_DIR=${work_path}/../../lib/paddle_inference
    
    cmake .. -DPADDLE_LIB=${LIB_DIR} \
      -DDEMO_NAME=${DEMO_NAME} \
      -DWITH_MKL=${WITH_MKL} \
      -DWITH_ONNXRUNTIME=${WITH_ONNXRUNTIME} \
      -DWITH_ARM=${WITH_ARM} \
      -DWITH_MIPS=${WITH_MIPS} \
      -DWITH_SW=${WITH_SW} \
      -DWITH_STATIC_LIB=OFF
    
    # 之后就可以编译了, 会生成resnet50_test
    ./compile.sh
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    1. 运行程序
    ./build/resnet50_test --model_file resnet50/inference.pdmodel --params_file resnet50/inference.pdiparams
    # 显示以下内容表示成功
    I0310 08:20:42.485941  6242 device_context.cc:737] oneDNN v2.5.4
    WARNING: Logging before InitGoogleLogging() is written to STDERR
    I0310 08:20:42.643239  6242 resnet50_test.cc:76] run avg time is 157.477 ms
    I0310 08:20:42.643280  6242 resnet50_test.cc:91] 0 : 0
    I0310 08:20:42.643291  6242 resnet50_test.cc:91] 100 : 2.04163e-37
    I0310 08:20:42.643296  6242 resnet50_test.cc:91] 200 : 2.1238e-33
    I0310 08:20:42.643299  6242 resnet50_test.cc:91] 300 : 0
    I0310 08:20:42.643303  6242 resnet50_test.cc:91] 400 : 1.6849e-35
    I0310 08:20:42.643309  6242 resnet50_test.cc:91] 500 : 0
    I0310 08:20:42.643317  6242 resnet50_test.cc:91] 600 : 1.05767e-19
    I0310 08:20:42.643327  6242 resnet50_test.cc:91] 700 : 2.04094e-23
    I0310 08:20:42.643334  6242 resnet50_test.cc:91] 800 : 3.85254e-25
    I0310 08:20:42.643342  6242 resnet50_test.cc:91] 900 : 1.52391e-30
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    如果只是学习使用官方教程到这里就结束了,但我的目的是想将Paddle,openCV以及Qt一起使用,因此下面还要探索如果简单方便的将Paddle库引入到Qt中。

    1. 移植Paddle库到QT

    Paddle库无非就是提供了头文件和库文件,要做的就是把其中的Paddle文件加入到Qt项目管理文件中,具体就是项目的.pro文件。废话不多说开造。

    # 使用QT creator新建一个paddleTest项目
    # paddleTest.pro文件中加入以下内容
    
    # 这个是自己的Paddle库所在位置
    PADDLE_PATH = /home/XXXXXXX/Downloads/paddle_inference/
    
    INCLUDEPATH += \
        $$PADDLE_PATH/paddle/include \
        $$PADDLE_PATH/third_party/install/cryptopp/include \
        $$PADDLE_PATH/third_party/install/glog/include \
        $$PADDLE_PATH/third_party/install/mkldnn/include \
        $$PADDLE_PATH/third_party/install/mklml/include \
        $$PADDLE_PATH/third_party/install/protobuf/include \
        $$PADDLE_PATH/third_party/install/xxhash/include \
        $$PADDLE_PATH/third_party/install/gflags/include
    
    LIBS += -L$$PADDLE_PATH/paddle/lib -lpaddle_inference
    LIBS += -L$$PADDLE_PATH/third_party/install/gflags/lib -lgflags
    LIBS += -L$$PADDLE_PATH/third_party/install/glog/lib -lglog
    LIBS += -L$$PADDLE_PATH/third_party/install/mkldnn/lib -lmkldnn
    LIBS += -L$$PADDLE_PATH/third_party/install/mklml/lib -liomp5 -lmklml_intel
    LIBS += -L$$PADDLE_PATH/third_party/install/protobuf/lib -lprotobuf
    LIBS += -L$$PADDLE_PATH/third_party/install/xxhash/lib -lxxhash
    
    # mkldnn库名字有点问题,我的Paddle库中是libmkldnn.so.0,使用下列命令来一个软链接,其它有几个动态库也是如此都有一个版本号,也可以加一个软链接
    ln -s libmkldnn.so.0 libmkldnn.so
    
    # 新建一个main.cc,复制Paddle-Inference-Demo/c++/cpu/resnet50/resnet50_test.cc内容到main.cc
    # 如果编译通过,那就没有问题了
    
    # 最后就是运行了,将前面下载的resnet50的推理模型复制到build-paddleTest-unknown-Debug
    # 下面命令运行程序, 和使前面和运行效果一致,表示成功移植
    ./paddleTest --model_file resnet50/inference.pdmodel --params_file resnet50/inference.pdiparams
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    到这里已经完成Paddle库和Qt一起使用,但还不够简单,每次加入的头文件和库文件也太多了,每次都要复制出来,太麻烦了。可以将这些文件提取出来放到固定文件,每次只需要加载这个文件就可以了。现成的方案是有的pkg-config,只需要提取出头文件,和库文件,再使用一个xxx.pc文件配置好,每次使用直接像opencv那样加载一下就完成了。库文件可以用前面提到的find . -name "*.so*" | xargs -i cp {} ./paddle_lib方法,这次不只提取.so动态库,.a的静态库也一并提取出来。

    # 进入paddle_inference目录
    # 提取库文件
    cd ~/Downloads/paddle_inference
    mkdir paddle_lib
    find . -name "*.so*" | xargs -i cp {} ./paddle_lib
    find . -name "*.a" | xargs -i cp {} ./paddle_lib
    
    # 复制头文件,因为头文件有结构要求,只能手动提取,注意这里的头文件包含第三方库的头文件
    mkdir paddle_include
    
    # 完成后将库文件复制到/usr/lib/
    # 将头文件复制到/usr/include/
    # 下面就是我复制完成后的头文件内容,包含paddle和第三方库所有头文件
    
    cpu_provider_factory.h     mkl_lapacke.h
    crypto                     mkl_lapack.h
    cryptopp                   mkl_service.h
    dnnl_config.h              mkl_spblas.h
    dnnl_debug.h               mkl_trans.h
    dnnl.h                     mkl_types.h
    dnnl.hpp                   mkl_version.h
    dnnl_ocl.h                 mkl_vml_defines.h
    dnnl_ocl.hpp               mkl_vml_functions.h
    dnnl_sycl.h                mkl_vml.h
    dnnl_sycl.hpp              mkl_vml_types.h
    dnnl_sycl_types.h          mkl_vsl_defines.h
    dnnl_threadpool.h          mkl_vsl_functions.h
    dnnl_threadpool.hpp        mkl_vsl.h
    dnnl_threadpool_iface.hpp  mkl_vsl_types.h
    dnnl_types.h               oneapi
    dnnl_version.h             onnxruntime_c_api.h
    experimental               onnxruntime_cxx_api.h
    gflags                     onnxruntime_cxx_inline.h
    glog                       onnxruntime_run_options_config_keys.h
    google                     onnxruntime_session_options_config_keys.h
    i_malloc.h                 paddle2onnx
    internal                   paddle_analysis_config.h
    mkl_blas.h                 paddle_api.h
    mkl_cblas.h                paddle_infer_contrib.h
    mkl_direct_blas.h          paddle_infer_declare.h
    mkl_direct_blas_kernels.h  paddle_inference_api.h
    mkl_direct_call.h          paddle_mkldnn_quantizer_config.h
    mkl_direct_lapack.h        paddle_pass_builder.h
    mkl_direct_types.h         paddle_tensor.h
    mkl_dnn.h                  provider_options.h
    mkl_dnn_types.h            utf8proc.h
    mkl.h                      xxhash.h
    
    # 最后库文件和头文件都重命名为paddle
    # 完成后可以再次使用Qt的测试项目测试一下,INCLUDEPATH就只添加/usr/include/paddle,LIBS只指定一次-L选项, -l选项保留,如下:
    INCLUDEPATH += /usr/include/paddle/
    
    LIBS += -L/usr/lib/paddle
    LIBS += -lpaddle_inference
    LIBS += -lgflags
    LIBS += -lglog
    LIBS +=	-lmkldnn
    LIBS +=	-liomp5 -lmklml_intel
    LIBS +=	-lprotobuf
    LIBS +=	-lxxhash
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    1. 编写paddle.pc文件

    pkg-config可以很方便管理头文件和库文件引用,只需要一个.pc文件。因此可以自己编写一个.pc文件,以后就可以方便的使用pkg-config引用paddle库了。
    经过以上提取,paddle所有头文件和第三方头文件我们都放到了/usr/include/paddle中。所有库文件,包含动态库和静态库都放到了/usr/lib/paddle中。

    cd /usr
    # 查找.pc文件存放位置
    find . -iname opencv4.pc
    # 找到如下位置
    ./lib/x86_64-linux-gnu/pkgconfig/opencv4.pc
    # 可以照着写一个自己的paddle.pc
    # Package Information for pkg-config
    
    prefix=/usr
    exec_prefix=${prefix}
    libdir=${exec_prefix}/lib/paddle
    includedir=${prefix}/include/paddle
    
    Name: Paddle
    Description: Open Source Computer Vision Library
    Version: 1.0.0
    Libs: -L${exec_prefix}/lib/paddle -lpaddle_inference -lgflags -lglog -lmkldnn -liomp5 -lmklml_intel -lprotobuf -lxxhash
    Cflags: -I${includedir}
    
    # 完成后看下是否成功
    pkg-config --cflags --libs paddle
    # 输出如下,如果需要的库不在这里面,可以自己更改paddle.pc增加
    -I/usr/include/paddle -L/usr/lib/paddle -lpaddle_inference -lgflags -lglog -lmkldnn -liomp5 -lmklml_intel -lprotobuf -lxxhash
    
    # 进入paddleTest项目直接编译运行,编译通过
    g++ -o main main.cc `pkg-config --cflags --libs paddle`
    # 复制推理模型到当前目录,运行程序,效果与前面一致
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    到这里已经完成了paddle.pc文件编写,下面就可以在Qt creator中以2句简单的命令引入paddle库了.

    CONFIG += link_pkgconfig
    PKGCONFIG += paddle
    
    • 1
    • 2
  • 相关阅读:
    【RTOS训练营】I2C和UART知识和预习安排 + 晚课提问
    实现基于 GitLab 的数据库 CI/CD 最佳实践
    Vue脚手架
    Spring - BeanPostProcessors 扩展接口
    Node.js的介绍与使用(附聊天案例)
    同城拼车网约车顺风车小程序公众号/同城顺风车小程序/顺风车小程序/拼车小程序
    内存分析总结
    python中的图像增强技术
    EO.Total:EO.WebBrowser 2023.3.31.0 Crack
    An Information-Theoretic Framework for Semi-Supervised Multi-Modality Learning
  • 原文地址:https://blog.csdn.net/weixin_45850062/article/details/136605234