尝试使用 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
而不是 1
中的 api->SetImage
。
cv::adaptiveThreshold
之后的图像是 1 个颜色 channel (每个像素 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_AUTO
或 tesseract::PSM_SINGLE_BLOCK
。
根据 header file 中的评论:
PSM_AUTO_ONLY = 2, ///< Automatic page segmentation, but no OSD, or OCR.
(除非这是故意的 - 我从未使用过 C++ 接口(interface))。
我尝试使用 pytesseract 和 Python 重现该问题,但在将 PSM 设置为 2 时出现错误。
我可能也在使用不同版本的 Tesseract。
结果很完美,而且应该与您帖子中的图片完美搭配。
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)
输出:
ojit_代码
关于c++ - Tesseract 检测质量非常低,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71905201/