【问题标题】:tesseract fails at simple number detectiontesseract 在简单的数字检测中失败
【发布时间】:2021-04-26 21:52:08
【问题描述】:

我想对这样的图像执行 OCR

这是一个以冒号作为小数分隔符的数字数据表。 它不嘈杂,对比度很好,白色背景上的黑色文字。 作为一个额外的预处理步骤,为了解决框架边框的问题,我剪掉了每个单元格,binarize 它,用白色边框填充它(以防止边缘问题)并只传递那个单一的单元格图像到tesseract。 我还查看了单个细胞图像,以确保切割过程按预期工作并且不会产生伪影。这是tesseract 的输入图像的两个示例:

很遗憾,tesseract 无法一致地解析这些内容。我没有发现可以正确识别所有 36 个值的配置。

在 SO 上存在几个类似的问题,通常的答案是对 --oem--psm 参数的特定组合的建议。所以我用 pytesseract 编写了一个 Python 脚本,它循环遍历从 0 到 3 的 --oem 的所有组合以及从 0 到 13 的 --psm 的所有值以及 lang=englang=deu。我忽略了引发错误的组合。

示例 1: 对于--psm 13 --oem 3,上面的“1,7”图像被错误识别为“4,7”,但“57”图像被正确识别为“57”。 p>

示例 2: 对于--psm 6 --oem 3,上述“1,7”图像被正确识别为“1,7”,但“57”图像被错误识别为“o/”。

还有什么对提高 tesseract 的输出质量有帮助的建议吗?

我的 tesseract 版本:

tesseract v4.0.0.20190314
 leptonica-1.78.0
  libgif 5.1.4 : libjpeg 8d (libjpeg-turbo 1.5.3) : libpng 1.6.34 : libtiff 4.0.9 : zlib 1.2.11 : libwebp 0.6.1 : libopenjp2 2.2.0
 Found AVX2
 Found AVX
 Found SSE

【问题讨论】:

    标签: ocr tesseract python-tesseract


    【解决方案1】:

    解决方案


    从原始图像中,我们可以看到有 5 个不同的行。

    每次迭代,我们都会取一行,应用归一化并读取。

    我们需要了解如何仔细设置图像索引。

    import cv2
    from pytesseract import image_to_string
    
    img = cv2.imread("0VXIY.jpg")
    gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    (h, w) = gry.shape[:2]
    
    start_index = 0
    end_index = int(h/5)
    

    问题我们为什么要声明开始和结束索引?

    我们希望在每次迭代中读取一行。让我们看一个例子:

    当前图片的高度和宽度分别为 645 和 1597 像素。

    根据索引划分图片:

    start-index end-index
    0 129
    129 258 (129 + 129)
    258 387 (258 + 129)
    387 516 (387 + 129)

    让我们看看图片是否可读?

    start-index end-index image
    0 129
    129 258
    258 387
    387 516

    不,它们不适合阅读,也许稍作调整可能会对我们有所帮助。喜欢:

    start-index end-index image
    0 129 - 20
    109 218
    218 327
    327 436
    436 545
    545 654

    现在它们适合阅读了。


    当我们对每一行应用除法归一化时:

    start-index end-index image
    0 109
    109 218
    218 327
    327 436
    436 545
    545 654

    现在我们阅读:

    1,7 | 57 | 71 | 59 | .70 | 65
    
    | 57 | 1,5 | 71 | 59 | 70 | 65
    
    | 71 | 59 | 1,3 | 57 | 70 | 60
    
    | 71 | 59 | 56 | 1,3 | 70 | 60
    
    | 72 | 66 | 71 | 59 | 1,2 | 56
    
    | 72 | 66 | 71 | 59 | 56 | 4,3
    

    代码:

    import cv2
    from pytesseract import image_to_string
    
    img = cv2.imread("0VXIY.jpg")
    gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    (h, w) = gry.shape[:2]
    # print(img.shape[:2])
    start_index = 0
    end_index = int(h/5) - 20
    
    for i in range(0, 6):
        # print("{}->{}".format(start_index, end_index))
        gry_crp = gry[start_index:end_index, 0:w]
        blr = cv2.GaussianBlur(gry_crp, (145, 145), 0)
        div = cv2.divide(gry_crp, blr, scale=192)
        txt = image_to_string(div, config="--psm 6")
        print(txt)
        start_index = end_index
        end_index = start_index + int(h/5) - 20
    

    【讨论】:

    • 感谢您的回复。您能解释一下为什么您认为按行(而不是像我一样按单元格)处理表格是有益的吗? “模糊和分裂”步骤背后的原因是什么?无论如何,您的解决方案仍然不比我得到的更好,因为有两个错误的单元格:第一行的“70”->“.70”和“1,3”->“4,3”。第一个错误可以通过过滤“.”来修复,所以这是一个小问题,但第二个错误更难检测。老实说,我很惊讶 tesseract 在如此简单且形状良好的输入上失败了。
    • 逐个单元格读取的结果与逐行读取的结果相同。因此,我更喜欢逐行阅读(与逐个单元格相比更便宜)。是的,关于“.70->70”和1.3->4.3,你是对的。我找到了制作“.70->70”和“1.3->4.3”的解决方案,但这次其他数字被误解了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-29
    • 2022-01-19
    • 1970-01-01
    • 1970-01-01
    • 2021-12-28
    相关资源
    最近更新 更多