【问题标题】:Can Tesseract OCR recognize subscripts and superscripts?Tesseract OCR 可以识别下标和上标吗?
【发布时间】:2020-12-13 04:01:27
【问题描述】:

我对文本片段中的下标和上标的一般识别有问题。

示例图片:

我使用 Tesseract 4.1.1 和 https://github.com/tesseract-ocr/tessdata_best 下的训练数据。许多选项都有默认值,除了:

  • tessedit_create_hocr = 1(以 HOCR 形式获取结果)
  • hocr_font_info = 1(获取额外的字体信息,如字体大小)
  • hocr_char_boxes = 1(获取基于字符的结果)

语言设置为英语。无论是页面分割模式 3 (PSM_AUTO_OSD) 还是 11 (PSM_SPARSE_TEXT) 或 12 (PSM_SPARSE_TEXT_OSD),下标/上标都无法正确识别。

在输出中,sub/sup-fragments 或多或少都是错误的:

  • “SubtextSub”被识别为“Subtextsu”,
  • “SuptextSub”被识别为“Suptexts?”
  • “P0”被识别为“Po”
  • “P100”被识别为“P1go”
  • “a2+b2”被识别为“a+b?”

使用 Tesseract 进行 OCR 有没有办法...?

  1. 优化下标/上标处理
  2. 获取有关已识别下标/上标的信息(在 hocr 输出中 - 最好是每个字符)

【问题讨论】:

  • 提供一点上下文:上标和下标在涉及化学式时很重要。上标也用于脚注。当上标在数字之后时,与普通文本的区别是相关的:Revenue in Q1 (in million USD): 54² is very different from Revenue in Q1 (in million USD): 542

标签: ocr tesseract


【解决方案1】:

按照该主题的其他问题/答案中的建议处理图像质量并没有真正改变任何事情。

首先从 tesseract-google-newsgroup 中获取这 2 个链接,这似乎真的是一个培训问题: link1link2

但在做了一些实验后,我发现使用的 OEM_DEFAULT-OCR 引擎模式并没有显示所需的信息。我找到了问题的部分解决方案。部分,因为我现在得到了关于 sub/sup 的大部分信息,而且在大多数情况下识别的字符都是正确的,但不是所有字符。

使用OEM_TESSERACT_ONLY-OCR引擎模式(=遗留模式)和Tess4J提供的一些API方法,我想出了以下java测试类:

public class SubSupEvaluator {
    public void determineSubSupCharacters(BufferedImage image) {
        //1. initialize Tesseract and set image infos
        TessBaseAPI handle = TessAPI1.TessBaseAPICreate();
        try {
            int bpp = image.getColorModel().getPixelSize();
            int bytespp = bpp / 8;
            int bytespl = (int) Math.ceil(image.getWidth() * bpp / 8.0);
            TessBaseAPIInit2(handle, new File("./tessdata/").getAbsolutePath(), "eng", TessOcrEngineMode.OEM_TESSERACT_ONLY);
            TessBaseAPISetPageSegMode(handle, TessPageSegMode.PSM_AUTO_OSD);
            TessBaseAPISetImage(handle, ImageIOHelper.convertImageData(image), image.getWidth(), image.getHeight(), bytespp, bytespl);

            //2. start actual OCR run
            TessBaseAPIRecognize(handle, null);

            //3. iterate over the result character-wise
            TessResultIterator ri = TessBaseAPIGetIterator(handle);
            TessPageIterator pi = TessResultIteratorGetPageIterator(ri);
            TessPageIteratorBegin(pi);
            do {
                //determine character
                Pointer ptr = TessResultIteratorGetUTF8Text(ri, TessPageIteratorLevel.RIL_SYMBOL);
                String character = ptr.getString(0);
                TessDeleteText(ptr); //release memory

                //determine position information
                IntBuffer leftB = IntBuffer.allocate(1);
                IntBuffer topB = IntBuffer.allocate(1);
                IntBuffer rightB = IntBuffer.allocate(1);
                IntBuffer bottomB = IntBuffer.allocate(1);
                TessPageIteratorBoundingBox(pi, TessPageIteratorLevel.RIL_SYMBOL, leftB, topB, rightB, bottomB);

                //write info to console
                System.out.println(String.format("%s - position [%d %d %d %d], subscript: %b, superscript: %b", character, leftB.get(), topB.get(),
                    rightB.get(), bottomB.get(), TessAPI1.TessResultIteratorSymbolIsSubscript(ri) == TessAPI1.TRUE,
                    TessAPI1.TessResultIteratorSymbolIsSuperscript(ri) == TessAPI1.TRUE));
            } while (TessPageIteratorNext(pi, TessPageIteratorLevel.RIL_SYMBOL) == TessAPI1.TRUE);
        } finally {
            TessBaseAPIDelete(handle); //release memory
        }
    }
}

旧模式仅适用于“正常”训练数据。使用“最佳”训练数据会带来错误。

【讨论】:

  • 您的回答似乎很有希望。我一直在寻找这个问题的答案。你能分享一个如何运行你的代码的例子吗?谢谢。
  • 我认为大多数信息都在答案中。这意味着您需要 Java 和 Tess4J 库(请参阅链接)。如何从图像文件创建 BuffedImage 可以在 StackOverflow 的众多问题中找到。
  • 啊,好的,谢谢。我正在尝试使用 Eclipse 在我的 Mac 上运行它。我正在尝试包含正确的 log4j 和 slf4j jar 文件。但我不断收到此错误:线程“main”中的异常 java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory at net.sourceforge.tess4j.Tesseract.(未知来源)
  • Log4j 有很多 jars :-) 尝试在其中包含带有 api 的那个。
【解决方案2】:

关于这个主题的信息很少。 增强子/上标字符识别(即使不是位置本身)的一种选择是通过预处理图像,例如使用cv2 / pil(也是pillow),然后对其进行tesseract。

How to detect subscript numbers in an image using OCR?

相关(但不回答问题):

https://www.mail-archive.com/tesseract-ocr@googlegroups.com/msg19434.html

https://github.com/tesseract-ocr/tesseract/blob/master/src/ccmain/superscript.cpp

【讨论】:

    【解决方案3】:

    你们如何看待让 tesseract 识别单个字母?

    Tesseract does not recognize single characters

    我尝试使用选项 --psm 10

    tesseract imTstg.png out5 --psm 10
    

    但它似乎没有工作。我正在考虑只运行 yolo 来检测单个字母。

    【讨论】:

      猜你喜欢
      • 2013-08-03
      • 2021-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多