hiroi-sora / PaddleOCR-json

OCR离线图片文字识别命令行windows程序,以JSON字符串形式输出结果,方便别的程序调用。提供各种语言API。由 PaddleOCR C++ 编译。
Apache License 2.0
975 stars 127 forks source link

使用代码调用有的电脑上成功,有的电脑上失败。 #146

Open broadcast98 opened 3 months ago

broadcast98 commented 3 months ago
#include <QApplication>
#include <QProcess>
#include <QStringList>
#include <QString>
#include <QThread>
#include <QDebug>
#include <QJsonObject>
#include <QJsonDocument>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QProcess *process = new QProcess();

    QString ocrdir = QApplication::applicationDirPath() + "/ocr";
    QString ocrfile = QApplication::applicationDirPath() + "/ocr/PaddleOCR-json.exe";
    qDebug() << "[startProcess] ocrdir:" << ocrdir;
    qDebug() << "[startProcess] ocrfile:" << ocrfile;

    process->setWorkingDirectory(ocrdir);

    process->start(ocrfile);

    if (!process->waitForStarted(5000)) {
        qDebug() << "[startProcess] Failed to start the process:" << process->errorString();
    }

    while (true) {

        qDebug() << "[startProcess] while loop ... ";

        if (process->waitForReadyRead()) {
            QByteArray output = process->readAllStandardOutput();
            QString strOut = QString::fromUtf8(output);

            qDebug() << "[startProcess] Initialization strOut: " << strOut;

            if (strOut.contains("OCR init completed.")) {
                break;
            }

            if (process->state() == QProcess::NotRunning) {
                throw std::runtime_error("OCR initialization failed 1");
            }
        }

        QThread::msleep(50);
    }

    qDebug() << "[startProcess] Initialization completed!";

    QJsonObject imgObj1 = {{"image_path", "test.png"}};
    QJsonDocument imgDoc2(imgObj1);
    QString imgStr1 = imgDoc2.toJson(QJsonDocument::Compact) + "\n";

    process->write(imgStr1.toUtf8());

    bool x = process->waitForBytesWritten();
    bool y = process->waitForReadyRead();
    qDebug() << "[startProcess] x:" << x;
    qDebug() << "[startProcess] y:" << y;

    qDebug() << "[startProcess] process->state:" << process->state();

    if (process->state() == QProcess::NotRunning) {
        throw std::runtime_error("OCR initialization failed 2");
    }

    qDebug() << "[startProcess] process->errorString:" << process->errorString();
    qDebug() << "[startProcess] process->exitCode:" << process->exitCode();

    QString current_image_resultx = process->readAllStandardOutput();
    qDebug() << "[startProcess] current_image_resultx:" << current_image_resultx;

    return a.exec();
}

上面的代码 有什么问题么?在一台电脑上current_image_resultx 有返回数据。另一台电脑上current_image_resultx 没有返回数据。 调用 PaddleOCR-json.exe 需要什么环境变量么?

控制台输出如下:

[startProcess] Initialization completed!
[startProcess] x: true
[startProcess] y: true
[startProcess] process->state: QProcess::Running
[startProcess] process->errorString: "Unknown error"
[startProcess] process->exitCode: 0
[startProcess] current_image_resultx: ""
Gavin1937 commented 3 months ago

process->errorString返回"Unknown error"应该是因为stderr是空的。先检查PaddleOCR-json是否正常运行。

可以用QT的readAllStandardOutputreadAllStandardError这两个函数和readyReadStandardOutputreadyReadStandardError这两个信号来检查PaddleOCR-json的stdout和stderr输出。

然后建议用QProcess的argumentsnativeArguments两个函数来检查QT启动PaddleOCR-json的具体命令和参数,接着你可以在cmd里面复现一下这些命令看看引擎的具体输出。

接着我建议在启动PaddleOCR-json时加入--models_path这个参数来指定模型库位置(就是PaddleOCR-json.exe文件同目录下的models文件夹),这样可以防止找不到模型库引发的无法运行。


其实,你可以直接用C++调用PaddleOCR-json的API,比如说:

#include <string>
#include "PaddleOCR-json/include/task.h"

int main()
{
    Task task = Task();
    task.init_engine();

    std::string json_output = task.run_ocr("{\"json\":\"input\"}");

    return 0;
}

更多例子请看 https://github.com/hiroi-sora/PaddleOCR-json/blob/main/cpp/src/main.cpp https://github.com/hiroi-sora/PaddleOCR-json/blob/main/cpp/src/task.cpp

只不过这样一来你就需要把PaddleOCR-json给编译进你的项目里了,具体文档请看这里

broadcast98 commented 3 months ago

process->errorString返回"Unknown error"应该是因为stderr是空的。先检查PaddleOCR-json是否正常运行。

可以用QT的readAllStandardOutputreadAllStandardError这两个函数和readyReadStandardOutputreadyReadStandardError这两个信号来检查PaddleOCR-json的stdout和stderr输出。

然后建议用QProcess的argumentsnativeArguments两个函数来检查QT启动PaddleOCR-json的具体命令和参数,接着你可以在cmd里面复现一下这些命令看看引擎的具体输出。

接着我建议在启动PaddleOCR-json时加入--models_path这个参数来指定模型库位置(就是PaddleOCR-json.exe文件同目录下的models文件夹),这样可以防止找不到模型库引发的无法运行。

其实,你可以直接用C++调用PaddleOCR-json的API,比如说:

#include <string>
#include "PaddleOCR-json/include/task.h"

int main()
{
    Task task = Task();
    task.init_engine();

    std::string json_output = task.run_ocr("{\"json\":\"input\"}");

    return 0;
}

更多例子请看 https://github.com/hiroi-sora/PaddleOCR-json/blob/main/cpp/src/main.cpp https://github.com/hiroi-sora/PaddleOCR-json/blob/main/cpp/src/task.cpp

只不过这样一来你就需要把PaddleOCR-json给编译进你的项目里了,具体文档请看这里

谢谢这么详细的指导。 我看了微信好像也是独立的ocr进程。 有空了再研究一下编译。