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_AUTO
或 tesseract::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
尝试使用 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_AUTO
或 tesseract::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