1

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

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

在此处输入图像描述

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

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

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

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

如果有一种区分粗体和非粗体文本的非 OCR 方式,可以在粗体文本周围放置边界框,我们可能会将这些延伸与 Tesseract 输出的字符/单词的边界框匹配(允许一些像素差)。我知道几十年前(也在这里)对此进行了研究,但是有没有真正做到这一点的开源软件?

4

1 回答 1

0

我发明了一些脚本:

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” - 它可以替换为另一个指标。我还没有找到更好的指标。

于 2021-07-03T20:58:14.207 回答