QT与paddleOCR2.6版本的联合使用(外加避坑注意事项)

效果如下所示:

首先说明我使用的环境和配置如下:

QT5.15.2+opencv4.5.2+VS2019+paddleocr2.6(截止到目前的最新版)+cpu部署

按照很多博主写过的那样进行部署编译:

先下载以下文件:

paddleocr2.6源码



     我是选择中英文超轻量PP-OCRV3的推理模型,三个都下载




paddleocr_inference

下载dirent-master

用来补充paddle-ocr2.6的头文件,进行编译参考博客链接:https://blog.csdn.net/Helloorl-C++文档类资源-CSDN文库

然后就可以开始进行自己的编译了,将下载的文件放到如下所示的文件夹中:

 我这里是将paddle_inference放到paddle_1中解压了。

下一步,打开cmake进行编译,如果没有安装的话,这里有参考地址:

CMake的安装(超级详细)_cmake安装_小码1111的博客-CSDN博客

打开cmake

 第一次点击configure,选择VS2019,x64

第二次点击configure,配置lib地址

第三次点击,如果配置完成即configure done,再点击generate

生成完成后,在之前创建的build下,打开ppocr.sln(官方建议release)

然后添加ppocr的项目包含头文件

这里注意还要添加dirent头文件,不然会报错,网上有相关链接!

先点击生成all_build,然后开始调试F5

会报错,但是不用管它

 打开build文件

点击进去release(新的)

 

 保证有红色框里面的dll文件,如果缺,可以搜索,复制粘贴过来。

接下来,在build文件夹下,cmd

首先输入CHCP 65001

Active code page: 65001

 然后输入:

.\build\Release\ppocr.exe system --det_model_dir=.\build\Release\ch_PP-OCRv3_det_infer --rec_model_dir=.\build\Release\ch_PP-OCRv3_rec_infer --image_dir=.\build\Release\imgs\11.jpg --rec_char_dict_path=.\build\Release\ppocr_keys_v1.txt

就会看到能否预测。

预测成功后,开始部署到QT上

部署到QT上,首先新建一个QT程序。

因为编译的问题,需要添加:

 pro文件如下:

QT       += core gui



greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++17


CONFIG(debug, debug|release) {
    QMAKE_CXXFLAGS_DEBUG += /MTd
}

CONFIG(release, debug|release) {
    QMAKE_CXXFLAGS_RELEASE += /MT
}


greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    mainwindow.cpp \
    paddle_ocr_src/args.cpp \
    paddle_ocr_src/clipper.cpp \
    paddle_ocr_src/ocr_cls.cpp \
    paddle_ocr_src/ocr_det.cpp \
    paddle_ocr_src/ocr_rec.cpp \
    paddle_ocr_src/paddleocr.cpp \
    paddle_ocr_src/paddlestructure.cpp \
    paddle_ocr_src/postprocess_op.cpp \
    paddle_ocr_src/preprocess_op.cpp \
    paddle_ocr_src/structure_table.cpp \
    paddle_ocr_src/utility.cpp

HEADERS += \
    mainwindow.h \
    paddle_ocr_include/args.h \
    paddle_ocr_include/autolog.h \
    paddle_ocr_include/clipper.h \
    paddle_ocr_include/ocr_cls.h \
    paddle_ocr_include/ocr_det.h \
    paddle_ocr_include/ocr_rec.h \
    paddle_ocr_include/paddle_api.h \
    paddle_ocr_include/paddleocr.h \
    paddle_ocr_include/paddlestructure.h \
    paddle_ocr_include/postprocess_op.h \
    paddle_ocr_include/preprocess_op.h \
    paddle_ocr_include/structure_table.h \
    paddle_ocr_include/utility.h

FORMS += \
    mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
#include everthing .h document;PWD stand for(current of pro's path)
INCLUDEPATH += $$PWD\..\3part\paddle_inference_install_dir\drient\include
INCLUDEPATH += $$PWD\..\3part\paddle_inference_install_dir\paddle\fluid\inference
INCLUDEPATH += $$PWD\..\3part\paddle_inference_install_dir\paddle\include
INCLUDEPATH += $$PWD\..\3part\\paddle_inference_install_dir\third_party\install\protobuf\include
INCLUDEPATH += $$PWD\..\3part\\paddle_inference_install_dir\third_party\install\glog\include
INCLUDEPATH += $$PWD\..\3part\\paddle_inference_install_dir\third_party\install\gflags\include
INCLUDEPATH += $$PWD\..\3part\\paddle_inference_install_dir\third_party\install\xxhash\include
INCLUDEPATH += $$PWD\..\3part\paddle_inference_install_dir\third_party\install\zlib\include
INCLUDEPATH += $$PWD\..\3part\paddle_inference_install_dir\third_party\install\onnxruntime\include
INCLUDEPATH += $$PWD\..\3part\paddle_inference_install_dir\third_party\install\paddle2onnx\include
INCLUDEPATH += $$PWD\..\3part\paddle_inference_install_dir\third_party\install\auto_log\include
INCLUDEPATH += $$PWD\..\3part\paddle_inference_install_dir\third_party\boost
INCLUDEPATH += $$PWD\..\3part\paddle_inference_install_dir\third_party\eigen3
INCLUDEPATH += $$PWD\..\3part\paddle_inference_install_dir\third_party\install\mklml\include
INCLUDEPATH += $$PWD\..\3part\paddle_inference_install_dir\third_party\install\mkldnn\include
#INCLUDEPATH += $$PWD\..\3part\opencv\include


#include everything .lib
LIBS += -L$$PWD\..\3part\paddle_inference_install_dir\paddle\lib -lpaddle_inference
LIBS += -L$$PWD\..\3part\paddle_inference_install_dir\third_party\install\mklml\lib -lmklml
LIBS += -L$$PWD\..\3part\paddle_inference_install_dir\third_party\install\mklml\lib -llibiomp5md
LIBS += -L$$PWD\..\3part\paddle_inference_install_dir\third_party\install\mkldnn\lib -lmkldnn
LIBS += -L$$PWD\..\3part\paddle_inference_install_dir\third_party\install\glog\lib -lglog
LIBS += -L$$PWD\..\3part\paddle_inference_install_dir\third_party\install\gflags\lib -lgflags_static
LIBS += -L$$PWD\..\3part\paddle_inference_install_dir\third_party\install\protobuf\lib -llibprotobuf
LIBS += -L$$PWD\..\3part\paddle_inference_install_dir\third_party\install\xxhash\lib -lxxhash
LIBS += -L$$PWD\..\3part\paddle_inference_install_dir\third_party\install\onnxruntime\lib -lonnxruntime
LIBS += -L$$PWD\..\3part\paddle_inference_install_dir\third_party\install\paddle2onnx\lib -lpaddle2onnx
#LIBS += -L$$PWD\..\3part\opencv -lopencv_world452

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "opencv2/core.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <vector>

#include <paddle_ocr_include/args.h>
#include <paddle_ocr_include/paddleocr.h>
#include <paddle_ocr_include/paddlestructure.h>

using namespace PaddleOCR;

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void check_params();
    void ocr(std::vector<cv::String> &cv_all_img_names);
    void structure(std::vector<cv::String> &cv_all_img_names);

private:
    Ui::MainWindow *ui;
    PaddleStructure *engine;
    PPOCR *ocr_result;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);


    int argc;
    char **argv;
    qDebug()<<"1";
    FLAGS_det_model_dir="../3part/model/ch_PP-OCRv3_det_infer";
    FLAGS_image_dir="F:/Paddle_OCR/paddle2.6/PaddleOCR-2.6.0/deploy/cpp_infer/build/Release/imgs/";
    FLAGS_rec_model_dir="../3part/model/ch_PP-OCRv3_rec_infer";
    FLAGS_rec_char_dict_path="../3part/ppocr_keys_v1.txt";

    check_params();

     if (!Utility::PathExists(FLAGS_image_dir)) {
       std::cerr << "[ERROR] image path not exist! image_dir: " << FLAGS_image_dir
                 << endl;
       exit(1);
     }
     std::vector<cv::String> cv_all_img_names{"F:/Paddle_OCR/paddle2.6/PaddleOCR-2.6.0/deploy/cpp_infer/build/Release/imgs/20.jpg"};//为了识别单张图片而弄的。
     std::cout << "total images num: " << cv_all_img_names[0] << endl;
     std::cout <<FLAGS_type<<endl;
     ocr(cv_all_img_names);

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::check_params()
{
    if (FLAGS_det) {
        if (FLAGS_det_model_dir.empty() || FLAGS_image_dir.empty()) {
          std::cout << "Usage[det]: ./ppocr "
                       "--det_model_dir=/PATH/TO/DET_INFERENCE_MODEL/ "
                    << "--image_dir=/PATH/TO/INPUT/IMAGE/" << std::endl;
          exit(1);
        }
      }
      if (FLAGS_rec) {
        std::cout
            << "In PP-OCRv3, rec_image_shape parameter defaults to '3, 48, 320',"
               "if you are using recognition model with PP-OCRv2 or an older "
               "version, "
               "please set --rec_image_shape='3,32,320"
            << std::endl;
        if (FLAGS_rec_model_dir.empty() || FLAGS_image_dir.empty()) {
          std::cout << "Usage[rec]: ./ppocr "
                       "--rec_model_dir=/PATH/TO/REC_INFERENCE_MODEL/ "
                    << "--image_dir=/PATH/TO/INPUT/IMAGE/" << std::endl;
          exit(1);
        }
      }
      if (FLAGS_cls && FLAGS_use_angle_cls) {
        if (FLAGS_cls_model_dir.empty() || FLAGS_image_dir.empty()) {
          std::cout << "Usage[cls]: ./ppocr "
                    << "--cls_model_dir=/PATH/TO/REC_INFERENCE_MODEL/ "
                    << "--image_dir=/PATH/TO/INPUT/IMAGE/" << std::endl;
          exit(1);
        }
      }
      if (FLAGS_table) {
        if (FLAGS_table_model_dir.empty() || FLAGS_det_model_dir.empty() ||
            FLAGS_rec_model_dir.empty() || FLAGS_image_dir.empty()) {
          std::cout << "Usage[table]: ./ppocr "
                    << "--det_model_dir=/PATH/TO/DET_INFERENCE_MODEL/ "
                    << "--rec_model_dir=/PATH/TO/REC_INFERENCE_MODEL/ "
                    << "--table_model_dir=/PATH/TO/TABLE_INFERENCE_MODEL/ "
                    << "--image_dir=/PATH/TO/INPUT/IMAGE/" << std::endl;
          exit(1);
        }
      }
      if (FLAGS_precision != "fp32" && FLAGS_precision != "fp16" &&
          FLAGS_precision != "int8") {
        cout << "precison should be 'fp32'(default), 'fp16' or 'int8'. " << endl;
        exit(1);
      }
}

void MainWindow::ocr(std::vector<cv::String> &cv_all_img_names)
{
    PPOCR ocr=PPOCR();
    qDebug()<<"here";
     std::vector<std::vector<OCRPredictResult>> ocr_results = ocr.ocr(cv_all_img_names, FLAGS_det, FLAGS_rec, FLAGS_cls);

     for (int i = 0; i < cv_all_img_names.size(); ++i) {
       if (FLAGS_benchmark) {
         cout << cv_all_img_names[i] << '\t';
         if (FLAGS_rec && FLAGS_det) {
           Utility::print_result(ocr_results[i]);
         } else if (FLAGS_det) {
           for (int n = 0; n < ocr_results[i].size(); n++) {
             for (int m = 0; m < ocr_results[i][n].box.size(); m++) {
               cout << ocr_results[i][n].box[m][0] << ' '
                    << ocr_results[i][n].box[m][1] << ' ';
             }
           }
           cout << endl;
         } else {
           Utility::print_result(ocr_results[i]);
         }
       } else {
         cout << cv_all_img_names[i] << "\n";
         Utility::print_result(ocr_results[i]);
         if (FLAGS_visualize && FLAGS_det) {
           cv::Mat srcimg = cv::imread(cv_all_img_names[i], cv::IMREAD_COLOR);
           if (!srcimg.data) {
             std::cerr << "[ERROR] image read failed! image path: "
                       << cv_all_img_names[i] << endl;
             exit(1);
           }
           std::string file_name = Utility::basename(cv_all_img_names[i]);

           Utility::VisualizeBboxes(srcimg, ocr_results[i],
                                    FLAGS_output + "/" + file_name);
         }
         cout << "***************************" << endl;
       }
     }
}

void MainWindow::structure(std::vector<cv::String> &cv_all_img_names)
{
    PaddleOCR::PaddleStructure engine = PaddleOCR::PaddleStructure();
      std::vector<std::vector<StructurePredictResult>> structure_results =
          engine.structure(cv_all_img_names, false, FLAGS_table);
      for (int i = 0; i < cv_all_img_names.size(); i++) {
        cout << "predict img: " << cv_all_img_names[i] << endl;
        for (int j = 0; j < structure_results[i].size(); j++) {
          std::cout << j << "\ttype: " << structure_results[i][j].type
                    << ", region: [";
          std::cout << structure_results[i][j].box[0] << ","
                    << structure_results[i][j].box[1] << ","
                    << structure_results[i][j].box[2] << ","
                    << structure_results[i][j].box[3] << "], res: ";
          if (structure_results[i][j].type == "table") {
            std::cout << structure_results[i][j].html << std::endl;
          } else {
            Utility::print_result(structure_results[i][j].text_res);
          }
        }
      }
}

main.cpp

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

QT里面对于log文件有不兼容问题,因此我采取了注释掉打印部分功能,来避免

详情可以参考我上传的资料:

链接如下:paddle-ocr-2-6.rar-C++文档类资源-CSDN文库

新的研究进展,利用paddleocr去识别多语种字符,对此进行部署。

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Helloorld_11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值