如何改进印地语文本提取?

2023-11-24

我正在尝试从 PDF 中提取印地语文本。我尝试了所有从 PDF 中提取内容的方法,但都不起作用。有解释为什么它不起作用,但没有答案。所以,我决定将PDF转换为图像,然后使用pytesseract提取文本。我已经下载了印地语训练数据,但这也给出了非常不准确的文本。

这是 PDF 中的实际印地语文本(下载链接):

Actual Hindi

到目前为止,这是我的代码:

import fitz

filepath = "D:\\BADI KA BANS-Ward No-002.pdf"

doc = fitz.open(filepath)
page = doc.loadPage(3)  # number of page
pix = page.getPixmap()
output = "outfile.png"
pix.writePNG(output)
from PIL import Image
import pytesseract

# Include tesseract executable in your path
pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"

# Create an image object of PIL library
image = Image.open('outfile.png')

# pass image into pytesseract module
# pytesseract is trained in many languages
image_to_text = pytesseract.image_to_string(image, lang='hin')

# Print the text
print(image_to_text)

这是一些输出示例:

कार बिता देवी व ०... नाम बाइुनान िक०क नाक तो
पति का नाव: रवजी लात. “50९... पिला का सामशामाव.... “पति का नाम: बादुलल
कान सब: 43 लसमनंध्या: 93९. मकान ंब्या: 3९
आप: 29 _ लिंग सी. | आइ 57 लिंग पुरुष आप: 62 लिंग सी
एजगल्णब्णस्य (बन्द जगाख्मिणण्य
नमः बायगी बसों ०४... नि बयावर्णो ०५०... निफर सनक नी
चिता का नामजबूजल वर्ष.“ ००० | पिला का नामब्राइलाल वर्षो... 0 2... | पिता कामामशुल चब्द .... “20०
|सकानसंब्या: 43९ बसवकंब्या: 43९. कान संब्या: 44
जाए: 27 लिंग सो कई: 27 नि खी मा लिंग पुरुष

这个问题有答案了我想用 python 抓取印地语(印度语言)pdf 文件,它似乎告诉了如何做到这一点,但没有提供任何解释。

有什么办法可以做到这一点吗?


我将给出一些如何处理图像的想法,但我会将其限制在给定文档的第 3 页,即问题中显示的页面。

为了将 PDF 页面转换为某些图像,我使用了pdf2image.

对于 OCR,我使用pytesseract,但不是lang='hin', I use lang='Devanagari',参见这超立方体 GitHub。一般来说,请确保完成提高输出质量来自 Tesseract 文档,尤其是页面分割方法.

这是整个过程的(冗长)描述:

  1. 对图像进行逆二值化以进行轮廓查找:黑色背景上的白色文本、形状等。
  2. 找到所有轮廓,并过滤掉两个非常大的轮廓,即这是两个表。
  3. Extract texts outside of the two tables:
    1. 屏蔽二值化图像中的表格。
    2. 进行形态闭合以连接剩余的文本行。
    3. 找到这些文本行的轮廓和边界矩形。
    4. Run pytesseract提取文本。
  4. Extract texts inside of the two tables:
    1. 从当前表格中更好地提取单元格:它们的边界矩形。
    2. For the first table:
      1. Run pytesseract按原样提取文本。
    3. For the second table:
      1. 填充数字周围的矩形,以防止 OCR 输出错误。
      2. 遮盖左侧(印地语)和右侧(英语)部分。
      3. Run pytesseract using lang='Devaganari'在左边,并使用lang='eng'位于正确的部分,以提高两者的 OCR 质量。

这就是整个代码:

import cv2
import numpy as np
import pdf2image
import pytesseract

# Extract page 3 from PDF in proper quality
page_3 = np.array(pdf2image.convert_from_path('BADI KA BANS-Ward No-002.pdf',
                                              first_page=3, last_page=3,
                                              dpi=300, grayscale=True)[0])

# Inverse binarize for contour finding
thr = cv2.threshold(page_3, 128, 255, cv2.THRESH_BINARY_INV)[1]

# Find contours w.r.t. the OpenCV version
cnts = cv2.findContours(thr, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

# STEP 1: Extract texts outside of the two tables

# Mask out the two tables
cnts_tables = [cnt for cnt in cnts if cv2.contourArea(cnt) > 10000]
no_tables = cv2.drawContours(thr.copy(), cnts_tables, -1, 0, cv2.FILLED)

# Find bounding rectangles of texts outside of the two tables
no_tables = cv2.morphologyEx(no_tables, cv2.MORPH_CLOSE, np.full((21, 51), 255))
cnts = cv2.findContours(no_tables, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
rects = sorted([cv2.boundingRect(cnt) for cnt in cnts], key=lambda r: r[1])

# Extract texts from each bounding rectangle
print('\nExtract texts outside of the two tables\n')
for (x, y, w, h) in rects:
    text = pytesseract.image_to_string(page_3[y:y+h, x:x+w],
                                       config='--psm 6', lang='Devanagari')
    text = text.replace('\n', '').replace('\f', '')
    print('x: {}, y: {}, text: {}'.format(x, y, text))

# STEP 2: Extract texts from inside of the two tables

rects = sorted([cv2.boundingRect(cnt) for cnt in cnts_tables],
               key=lambda r: r[1])

# Iterate each table
for i_r, (x, y, w, h) in enumerate(rects, start=1):

    # Find bounding rectangles of cells inside of the current table
    cnts = cv2.findContours(page_3[y+2:y+h-2, x+2:x+w-2],
                            cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    inner_rects = sorted([cv2.boundingRect(cnt) for cnt in cnts],
                         key=lambda r: (r[1], r[0]))

    # Extract texts from each cell of the current table
    print('\nExtract texts inside table {}\n'.format(i_r))
    for (xx, yy, ww, hh) in inner_rects:

        # Set current coordinates w.r.t. full image
        xx += x
        yy += y

        # Get current cell
        cell = page_3[yy+2:yy+hh-2, xx+2:xx+ww-2]

        # For table 1, simply extract texts as-is
        if i_r == 1:
            text = pytesseract.image_to_string(cell, config='--psm 6',
                                               lang='Devanagari')
            text = text.replace('\n', '').replace('\f', '')
            print('x: {}, y: {}, text: {}'.format(xx, yy, text))

        # For table 2, extract single elements
        if i_r == 2:

            # Floodfill rectangles around numbers
            ys, xs = np.min(np.argwhere(cell == 0), axis=0)
            temp = cv2.floodFill(cell.copy(), None, (xs, ys), 255)[1]
            mask = cv2.floodFill(thr[yy+2:yy+hh-2, xx+2:xx+ww-2].copy(),
                                 None, (xs, ys), 0)[1]

            # Extract left (Hindi) and right (English) parts
            mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE,
                                    np.full((2 * hh, 5), 255))
            cnts = cv2.findContours(mask,
                                    cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
            cnts = cnts[0] if len(cnts) == 2 else cnts[1]
            boxes = sorted([cv2.boundingRect(cnt) for cnt in cnts],
                           key=lambda b: b[0])

            # Extract texts from each part of the current cell
            for i_b, (x_b, y_b, w_b, h_b) in enumerate(boxes, start=1):

                # For the left (Hindi) part, extract Hindi texts
                if i_b == 1:

                    text = pytesseract.image_to_string(
                        temp[y_b:y_b+h_b, x_b:x_b+w_b],
                        config='--psm 6',
                        lang='Devanagari')
                    text = text.replace('\f', '')

                # For the left (English) part, extract English texts
                if i_b == 2:

                    text = pytesseract.image_to_string(
                        temp[y_b:y_b+h_b, x_b:x_b+w_b],
                        config='--psm 6',
                        lang='eng')
                    text = text.replace('\f', '')

                print('x: {}, y: {}, text:\n{}'.format(xx, yy, text))

并且,这是输出的前几行:

Extract texts outside of the two tables

x: 972, y: 93, text: राज्य निर्वाचन आयोग, राजस्थान
x: 971, y: 181, text: पंचायत चुनाव निर्वाचक नामावली, 2021
x: 166, y: 610, text: मिश्र का बाढ़ ,श्रीराम की नॉगल
x: 151, y: 3417, text: आयु 1 जनवरी 2021 के अनुसार
x: 778, y: 3419, text: पृष्ठ संख्या : 3 / 10

Extract texts inside table 1

x: 146, y: 240, text: जिलापरिषद का नाम : जयपुर
x: 1223, y: 240, text: जि° प° सदस्य निर्वाचन क्षेत्र : 21
x: 146, y: 327, text: पंचायत समिति का नाम : सांगानेर
x: 1223, y: 327, text: पं° स° सदस्य निर्वाचन क्षेत्र : 6
x: 146, y: 415, text: ग्रामपंचायत : बडी का बांस
x: 1223, y: 415, text: वार्ड क्रमांक : 2
x: 146, y: 502, text: विधानसभा क्षेत्र की संख्या एवं नाम:- 56-बगरु

Extract texts inside table 2

x: 142, y: 665, text:
1 RBP2469583
नाम: आरती चावला
पिता का नामःलाला राम चावला
मकान संख्याः १९
आयुः 21 लिंगः स्त्री

x: 142, y: 665, text:
Photo is
Available

x: 867, y: 665, text:
2 MRQ3101367
नामः सूरज देवी
पिता का नामःरामावतार
मकान संख्याः डी /18
आयुः 44 लिंगः स्त्री

x: 867, y: 665, text:
Photo is
Available

我使用手动逐个字符比较检查了一些文本,认为它看起来相当不错,但无法理解印地语或阅读梵文脚本,我无法评论 OCR 的整体质量。请告诉我!

令人烦恼的是,数字9从相应的“卡”中被错误地提取为2。我认为,发生这种情况是由于与文本的其余部分相比字体不同,并且结合lang='Devanagari'。无法找到解决方案 - 不从“卡片”中单独提取矩形。

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.19041-SP0
Python:        3.9.1
PyCharm:       2021.1.1
NumPy:         1.19.5
OpenCV:        4.5.2
pdf2image      1.14.0
pytesseract:   5.0.0-alpha.20201127
----------------------------------------
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何改进印地语文本提取? 的相关文章

随机推荐

  • VSTS 中 Android 应用程序的 Gradle 构建在内存不足后失败

    我在 VSTS 中有一个 gradle 构建 正在构建 Android 应用程序 但它失败并出现以下错误 构建机器真的只有很少的内存吗 还是我应该更改一些设置gradle properties 例如这org gradle jvmargs设置
  • WebBrowser DocumentCompleted 事件多次触发

    我一直在研究这个东西 每个人似乎都同意解决方案是检查ReadyState直到设置为 完成 但实际上该事件有时会被触发ReadyState多次设置为 完成 我认为对于那个蹩脚的 NET WebBrowser 没有解决方案 但如果我使用底层 D
  • Java 中抛出异常

    我有一个关于在 Java 中抛出异常的问题 这似乎是我这边的一种误解 我想自己澄清一下 我一直在读到处理异常代码的两种基本方法是 1 在 try 块中使用 throw new 抛出异常 并立即在 catch 块中捕获它 所谓的 try th
  • 所有者绘制的进度条中的动画“发光”(ListView/DataGridView)

    我注意到 NET 2 0 Winforms 中的沼泽标准 ProgressBar 在 Vista 中确实显示为精美的动画发光条 但是 使用 ProgressBarRenderer 通常在尝试在所有者绘制的列表视图 网格视图或其他此类控件中绘
  • ChartJS 折线图 - 多条线,在工具提示上显示一个值

    我正在尝试制作一个图表 该图表必须显示每个客户的帐户变动 我正在尝试做什么 我有树线 第一行 最低余 额 如果客户的余额低于最低余额 余额 他的余额将从他的银行帐户自动加载 第二行 当前余额 第三行 最大余额 如果客户的余额超过最大余额 他
  • 想要使用 VBScript 运行不同文件夹中的 .bat 文件

    我正在尝试使用 VBScript 运行 bat 文件 当在与 bat 相同的文件夹中执行时 我可以让 VBScript 工作 但是 我不知道如何使其在文件夹外成功运行 Dim shell Set shell CreateObject WSc
  • Python 中 C _PyTime_t 的值

    长时间睡觉时 比如跑步time sleep 3 3 3 在 Python 3 中 程序返回 OverflowError 并显示错误消息 时间戳太大 无法转换为 C PyTime t 我最多可以睡多久 该值应为 9223372036 8547
  • 是否可以读取.net中的.eml文件

    我想知道是否可以解析 dot net 中的 eml 和 msg 文件 最好来自内存流 以便我可以在 ASP Net 页面上使用它们 EML MIME 消息 在大多数情况下 EML 是带有邮件消息的 MIME 编码文件 EML 文件的常见来源
  • 如果 web.xml 中有两个与请求匹配的 servlet 映射,会发生什么情况?

    如果 web xml 中有两个与请求匹配的 servlet 映射 会发生什么情况 它选择最具体的吗 例如 如果我有以下 xml 并且请求到达 something 而它转到 someservlet 或 everything else serv
  • 在 Android 的列表视图中滑动时显示删除按钮

    扩展另一个 Stackoverflow 问题 我实现了一些手势检测代码 以便我可以检测列表视图 位于 FrameLayout 中 中的行何时被滑动 我在这里关注了达米安关于如何从适配器获取单个行 视图的问题 答案 如何获取列表视图中行的位置
  • imaplib2 :imap.gmail.com 处理程序 BYE 响应:系统错误

    我正在更新一个 python 脚本 该脚本检查 IMAP 是否有新电子邮件 并在有新电子邮件时发送推送通知 问题是每隔几个小时我就会崩溃一次 起初我不太明白发生了什么 但后来我发现M debug 4这给了我一个很好的输出 但我仍然不明白是什
  • 用于最小化其他应用程序的批处理文件

    我怎样才能有一个打开应用程序的bat文件 让我们称之为firefox exe 我如何调用bat文件或任何其他脚本 即vbs 来最小化应用程序 即firefox exe 然后在一两分钟后关闭它 请注意start min不起作用 下面是我的脚本
  • 如何在 Vaadin 8 中添加验证器?

    在 Vaadin 7 中有一个 addValidator 函数 但在 Vaadin 8 中它不存在 Vaadin 7 示例 TextField user new TextField User user setRequired true us
  • 使用 THREE.OBJLoader 渲染 OBJ 文件

    如何使用 THREE OBJLoader 方法渲染 OBJ 文件 我有一个示例 OBJ 格式 但它不会渲染任何内容 也不会在 chrome 开发工具中看到错误 查看 OBJLoader 使用示例 https github com mrdoo
  • 在 ncurses 中实现文本滚动的推荐方法是什么?

    我正在尝试实现一个 ncurses 应用程序 其文本滚动效果如下 推荐的方法是什么 这是我所知道的 您可以使用scroll将文本缓冲区向上或向下移动 1 行 但是 如果向下滚动 您最终会在顶部出现一个空行 如果向上滚动 则会在底部出现一个空
  • C++ 将十六进制字符串转换为有符号整数

    我想在 C 中将十六进制字符串转换为 32 位有符号整数 例如 我有十六进制字符串 fffefffe 其二进制表示形式为 11111111111111101111111111111110 其有符号整数表示形式为 65538 我如何在 C 中
  • 如何将 groupby() 和 value_counts() 转换为多个饼图/条形图

    假设我有一个数据框 并且正在查看其中的 2 列 2 个系列 使用其中一列 no employees 下面 有人可以帮我弄清楚如何创建 6 个不同的饼图或条形图 每个 no employees 分组 1 个 来说明处理列中 是 否 值的值计数
  • C++程序需要文件关联

    我正在分发一个免费软件产品 该产品可以读取和写入具有唯一扩展名的文本文件 我希望双击这样的文件会自动启动该应用程序 在 Windows 7 Professional 上进行开发时 我设置了一个关联 以便在双击时打开文件 方法是右键单击文件
  • 奇怪的UTF8字符串比较

    我在 UTF8 字符串比较方面遇到了这个问题 我真的不知道 它开始让我头疼 请帮帮我 基本上我有一个来自 UTF8 编码的 xml 文档的字符串 Mina Tidigare anst llningar 当我将该字符串与我自己输入的完全相同的
  • 如何改进印地语文本提取?

    我正在尝试从 PDF 中提取印地语文本 我尝试了所有从 PDF 中提取内容的方法 但都不起作用 有解释为什么它不起作用 但没有答案 所以 我决定将PDF转换为图像 然后使用pytesseract提取文本 我已经下载了印地语训练数据 但这也给