Tesseract 检测质量非常低

Tesseract very low detection quality

尝试使用 tesseract 读取一些数据,但它已经在为日期和时间而苦苦挣扎,所以我创建了一个最小的测试用例。

代码:

#include <string>
#include <sstream>
#include <tesseract/baseapi.h>
#include <leptonica/allheaders.h>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>
#include <boost/algorithm/string/trim.hpp>
using namespace std;
using namespace cv;

int main(int argc, const char * argv[]) {

    string outText, imPath = argv[1];
    cv::Mat image_final = cv::imread(imPath, CV_8UC1);

    tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI();
    api->Init(NULL, "eng", tesseract::OEM_LSTM_ONLY);
    api->SetPageSegMode(tesseract::PSM_AUTO_ONLY);
    cv::adaptiveThreshold(image_final,image_final,255,ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY,11,2);

    api->SetImage(image_final.data, image_final.cols, image_final.rows, 3, image_final.step);
    api->SetVariable("tessedit_char_whitelist", "0123456789- :");
    outText = string(api->GetUTF8Text());
    api->End();

    std::istringstream iss(outText);

    for (std::string line; std::getline(iss, line); ) {
        boost::algorithm::trim(line);
        if (!line.empty()) cout << line << endl;
    }

    cv::imwrite("out.png", image_final);

    return 0;
}

输出:

1122-03-08 18:10
2122-030 18:10

我什至尝试将这些字符列入白名单(在最终版本中不会是这种情况),但仍然得到非常糟糕的结果。

看起来主要问题是将 bytes_per_pixel 设置为 3 而不是 api->SetImage 中的 1

cv::adaptiveThreshold 之后的图像是 1 个颜色通道(每个像素 1 个字节)而不是 3 个。

api->SetImage(image_final.data, image_final.cols, image_final.rows, 3, image_final.step);替换为:

api->SetImage(image_final.data, image_final.cols, image_final.rows, 1, image_final.step);

cv::imread(imPath, CV_8UC1)替换为cv::imread(imPath, cv::IMREAD_GRAYSCALE)


您也可以尝试将 tesseract::PSM_AUTO_ONLY 替换为 tesseract::PSM_AUTOtesseract::PSM_SINGLE_BLOCK

根据header file中的评论:

PSM_AUTO_ONLY = 2, ///< Automatic page segmentation, but no OSD, or OCR.

(除非这是故意的 - 我从未使用过 C++ 接口)。


我曾尝试使用 pytesseract 和 Python 重现该问题,但在将 PSM 设置为 2 时出现错误。
我可能也在使用不同版本的 Tesseract。

结果很完美,它应该与您 post 中的图像完美搭配。

Python代码:

import cv2
from pytesseract import pytesseract

# Tesseract path
pytesseract.tesseract_cmd = "C:\Program Files\Tesseract-OCR\tesseract.exe"

img = cv2.imread("out.png", cv2.IMREAD_GRAYSCALE)  # Read input image as Grayscale
  
text = pytesseract.image_to_string(img, config="-c tessedit"
                                               "_char_whitelist=' '0123456789-:"
                                               " --psm 3 "
                                               "lang='eng'")

print(text)

输出:
2022-03-08 18:19:15