【问题标题】:Detecting bold (and italic) text in an image检测图像中的粗体(和斜体)文本
【发布时间】:2021-05-17 22:33:04
【问题描述】:

我想检测页面图像中的粗体(可能还有斜体)文本——想想 TIFF 或图像 PDF。我需要指向任何这样做的开源软件的指针。

这是一个词典条目的图片(来自 Tzeltal--西班牙语词典),说明了这样的文本:

第一行是粗体,然后是斜体,然后是“normal”;第二个有几个粗体字,然后是几个正常字体。格式表示隐式结构:粗体表示词条,斜体表示词性,正常表示大多数其他内容。如果不知道什么是粗体/斜体/正常,就不可能将这些条目解析为结构化文本(如 XML)。

当我们的字典解析项目几年前处于活动状态时,我们使用 Tesseract 版本 3 对图像进行 OCR,并使用 hocr 输出为我们提供页面上的位置信息(例如,分离字典中的不同条目至关重要)。 hocr 输出还包括粗体的标签“strong”和斜体的标签“em”。虽然“em”标签相当准确,但“strong”标签几乎是随机的。现在是 Tesseract doesn't even try (see also) 的第 4 版。您仍然可以告诉 tesseract 使用旧引擎,但正如我所说,这似乎完全不准确,至少在我们提供给它的文本上是这样。

区分粗体和普通文本似乎并不难;即使在那个距离我看不懂文字,我也可以站在离显示器很远的地方,挑选出粗体和非粗体。 (我想判断整个文本是粗体还是非粗体会更难,但是当两者都出现时区分它们似乎很容易——对人类来说。)

我听说 ABBYY FineReader 会输出有关字体样式的信息,但由于各种原因,这对我们的应用程序不起作用。

如果有一种区分粗体和非粗体文本的非 OCR 方法,可以在粗体文本周围放置边界框,我们可能会将这些延伸与 Tesseract 输出的字符/单词的边界框匹配(允许对于几个像素的差异)。我知道有research on this decades ago(也有here),但是有没有开源软件可以真正做到这一点?

【问题讨论】:

    标签: ocr hocr


    【解决方案1】:

    我发明了一些脚本:

    KERNEL = np.asarray([
        [1, 1, 1, 1],
        [1, 1, 1, 1],
        [1, 1, 1, 1],
    ], np.uint8)
    KERNEL_ITALIC = np.asarray([
        [0, 0, 1, 1],
        [0, 0, 1, 1],
        [0, 0, 1, 1],
        [0, 1, 1, 0],
        [0, 1, 1, 0],
        [0, 1, 1, 0],
        [1, 1, 0, 0],
        [1, 1, 0, 0],
        [1, 1, 0, 0],
    ], np.uint8)
    
    def pre_process_italic(img):
        img_f = cv2.flip(img, 1)
    
        img = cv2.erode(img, KERNEL_ITALIC, iterations=1)
        img = cv2.dilate(img, KERNEL, iterations=1)
    
        img_f = cv2.erode(img_f, KERNEL_ITALIC, iterations=1)
        img_f = cv2.dilate(img_f, KERNEL, iterations=1)
        img_f = cv2.flip(img_f, 1)
        return img, img_f
    
    def apply_func_italic(bbox, original, preprocessed):
    
        b_1 = bbox[1]
        b_3 = bbox[3]
        b_0 = bbox[0]
        b_2 = bbox[2]
    
        a, b = np.mean(original[b_1:b_3, b_0:b_2]), np.mean(preprocessed[b_1:b_3, b_0:b_2])
    
        return get_ratio(a, b)
    
    def get_ratio(a, b):
        return ((a - b) / (a + b + 1e-8)) * 2
    

    这个 python 函数获取带有文本的图像,并使一些 opencv 函数变形处理。之后,该函数返回两个图像:原始图像和处理后的图像,在此之后,您所需要的只是拥有单词的边界框并遍历它们并计算原始图像上“ON”像素与处理后的比率。有“get_ratio” - 它可以替换为另一个指标。我还没有找到更好的指标。

    【讨论】:

    • 所以,无论如何,主要想法是使用斜体样式沿垂直轴有些不对称的情况——这就是我在原始图像和水平翻转图像上使用 KERNEL_ITALIC 的原因
    • 谢谢!我想这是一个部分答案,即如何防止斜体混淆粗体与非粗体度量。 FWIW,我有一个小团队致力于解决更大的问题 - 检测粗体文本 - 他们通过使用 erode() 函数取得了一些成功,这似乎使其输出中粗体和非粗体之间的比率更大.没有它,像素比不是很准确,例如带有像“i”和“l”这样的字母的单词本质上比像“M”和“W”这样的单词具有更少的黑色像素(即使是可变宽度字体)。
    • 我认为您需要计算整个单词的粗体指标。我使用算法来检测粗体字,我的准确率非常好@MikeMaxwell
    猜你喜欢
    • 2013-01-07
    • 1970-01-01
    • 1970-01-01
    • 2013-02-24
    • 1970-01-01
    • 2011-10-02
    • 1970-01-01
    • 2011-07-18
    • 1970-01-01
    相关资源
    最近更新 更多