You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++中提升Tesseract OCR对旋转图像的识别准确率?

如何在C++中提升Tesseract OCR对旋转图像的识别准确率?

嘿,我之前也踩过Tesseract处理任意角度旋转图像的坑!PSM_AUTO_OSD确实只擅长处理90°、180°这类整数倍的旋转,碰到任意倾斜的文本就容易拉胯。下面是我亲测有效的几个解决思路,你可以试试:

1. 先做图像倾斜校正(核心步骤)

Tesseract的方向检测模块对非90°倍数的倾斜支持很差,所以第一步得用OpenCV先把图像转正。我当时用的是基于轮廓最小外接矩形的方法来计算倾斜角度,然后旋转校正:

#include <opencv2/opencv.hpp>
#include <tesseract/baseapi.h>
#include <algorithm>

// 计算图像的倾斜角度
double getSkewAngle(cv::Mat &img) {
    // 转灰度图+二值化
    cv::Mat gray, binary;
    cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);
    cv::threshold(gray, binary, 0, 255, cv::THRESH_BINARY_INV + cv::THRESH_OTSU);

    // 过滤小轮廓,只保留有效文本轮廓
    std::vector<std::vector<cv::Point>> contours;
    cv::findContours(binary, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
    contours.erase(std::remove_if(contours.begin(), contours.end(),
        [](const std::vector<cv::Point>& c) { return cv::contourArea(c) < 100; }), contours.end());

    if (contours.empty()) return 0.0;

    // 取最大轮廓的最小外接矩形计算角度
    auto largestContour = *std::max_element(contours.begin(), contours.end(),
        [](const std::vector<cv::Point>& a, const std::vector<cv::Point>& b) {
            return cv::contourArea(a) < cv::contourArea(b);
        });
    cv::RotatedRect rect = cv::minAreaRect(largestContour);
    double angle = rect.angle;

    // 调整角度范围,确保旋转后文本正向
    if (angle < -45) angle += 90;
    return -angle;
}

// 旋转图像并校正倾斜
cv::Mat deskewImage(cv::Mat &img, double angle) {
    cv::Point2f center(img.cols / 2.0, img.rows / 2.0);
    cv::Mat rotMat = cv::getRotationMatrix2D(center, angle, 1.0);
    cv::Mat deskewed;
    cv::warpAffine(img, deskewed, rotMat, img.size(), cv::INTER_CUBIC, cv::BORDER_REPLICATE);
    return deskewed;
}

把图像转正后再喂给Tesseract,识别准确率会提升一大截!

2. 优化Tesseract的配置参数

除了PSM_AUTO_OSD,还要搭配合适的OEM模式和其他参数:

  • 强制使用LSTM引擎(Tesseract 5默认是,但显式设置更稳妥):tess->SetOEMMode(tesseract::OEM_LSTM_ONLY);
  • 如果校正后的图像文本规整,可以试试PSM_SINGLE_BLOCK或者PSM_AUTO,有时候比PSM_AUTO_OSD更稳定
  • 针对噪点多的图像,可以关闭系统词典减少干扰:tess->SetVariable("load_system_dawg", "false");(按需使用)

完整调用示例:

int main() {
    cv::Mat img = cv::imread("rotated_text.jpg");
    double skewAngle = getSkewAngle(img);
    cv::Mat deskewedImg = deskewImage(img, skewAngle);

    // 初始化Tesseract
    tesseract::TessBaseAPI tess;
    if (tess.Init(nullptr, "eng", tesseract::OEM_LSTM_ONLY)) {
        std::cerr << "初始化Tesseract失败!" << std::endl;
        return -1;
    }
    tess.SetPageSegMode(tesseract::PSM_AUTO);
    tess.SetImage(deskewedImg.data, deskewedImg.cols, deskewedImg.rows, 3, deskewedImg.step);
    
    // 识别文本
    char* outText = tess.GetUTF8Text();
    std::cout << "识别结果:\n" << outText << std::endl;

    // 释放资源
    tess.End();
    delete[] outText;
    return 0;
}

3. 增强图像预处理效果

如果旋转后的图像有模糊、噪点,先做预处理优化:

  • 高斯模糊去噪:cv::GaussianBlur(gray, gray, cv::Size(3,3), 0);
  • 自适应二值化(适配光照不均的场景):cv::adaptiveThreshold(gray, binary, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY_INV, 11, 2);
  • 去除小噪点:用开运算过滤,cv::morphologyEx(binary, binary, cv::MORPH_OPEN, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(2,2)));

这些步骤能让Tesseract更容易捕捉到文本的清晰特征。

备注:内容来源于stack exchange,提问作者OMKAR GULAMBE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 16:13:10