识别以任意角度旋转的 PDF 文件中的文本

问题描述 投票:0回答:5

我有一个简单的程序(来自 docTR 库文档的代码),可以识别 pdf 文件中的文本。如果文本完全对齐,则文本识别不会出现问题,但如果文档向右或向左旋转,则文本识别就会出现问题。

enter image description here enter image description here

我可能会收到不仅精确旋转 90,180 或 270 度的文档。弯曲的扫描文档可以以任何角度旋转(如上图所示)。

我希望在您的帮助下找到一个解决方案,帮助我直接旋转 pdf 中的表格/文本(或整个 pdf),以便于文本识别,如下图所示。

enter image description here

也许已经有类似的解决方案,但我还没有找到。如果您向我指出现有的解决方案或帮助我用自己的解决方案编写代码,我将不胜感激。

from doctr.io import DocumentFile
from doctr.models import ocr_predictor

ocr = ocr_predictor(pretrained=True)

doc = DocumentFile.from_pdf("my/path.pdf")
result = ocr(doc)
result.show(doc)
python tensorflow ocr doctr
5个回答
3
投票

这些是我对所提出问题的想法:

  • 如果您从纸上扫描表格,则文档(即使是 pdf 格式)包含图像
  • 您知道您需要旋转文档才能让 docTR 阅读它,但从我在 docTR 存储库中读到的内容来看,您还可以 将 pdf 转换为图像并使 docTR 将其扫描为图像。
  • 但是,为什么要将 pdf 制作成图像呢?我认为如果文件是图像,那么执行接下来的两个步骤可能会更容易:
  • 首先您需要知道要旋转图像的角度(以度数或弧度为单位 - 每个文件不同)。为此,您需要扫描图像中的“长直线”并获取它们的角度(表格边框)。您将获得许多角度,而您只需要一个,因此您可能需要发挥一点创意(例如,您可以在最后一步中使用 docTR 多次扫描文件以获得不同的角度,衡量结果是否成功根据提取的数据量)
  • 一旦获得角度(或多个角度),您就可以旋转图像文件到您之前计算的特定角度
  • 最后一步:使用docTR扫描旋转后的图像

我知道这不是一个片段、复制粘贴的解决方案。希望您能找到更简单的方法到达那里。但如果没有更简单的方法的话,这将是我的方法。


1
投票

您可以使用OCRmyPDF,这是非常好的OCR库:

ocrmypdf --rotate-pages input_scanned.pdf

该标志可以修复错误旋转的页面。我没有

doctr
的经验。


1
投票

您可以使用在旋转文档上训练过的检测模型,并相应地传递选项

assume_straight_pages

predictor = detection_predictor('db_resnet50_rotation', pretrained=True, assume_straight_pages=False, preserve_aspect_ratio=True)

这是官方文档


1
投票

在使用 DocTR 执行您的任务之前。您可以使用 tesseract OCR 根据文本对齐方式旋转 pdf 图像。这里提供了源代码和详细实现: https://pyimagesearch.com/2022/01/31/ Correcting-text-orientation-with-tesseract-and-python/

您的流程可能如下所示:

  1. 阅读 pdf 并获取图像。
  2. 将图像发送到 tesseract ocr 进行重新对齐。
  3. 将响应发送至 DocTR 进行字符识别。

1
投票

第 1 步:将 pdf 转换为图像。

第2步:使用opencv读取图像

import numpy
import math
import cv2
import matplotlib.pyplot as plt

img = cv2.imread("test.png",0) #grayscale

第 3 步:根据需要进行预处理。请参阅阈值处理等(未完成,因为您的图像示例不需要)

第 4 步:使用 Canny 边缘检测和霍夫线

dst = cv2.Canny(img, 50, 200, None, 3) #see Canny docs
lines = cv2.HoughLines(dst, 1, np.pi / 180, 150, None, 0, 0) # See docs

第 5 步:将所有线条角度转换为度数并找到最合适的角度。

deg_lines = [round(np.rad2deg(i[0][1]))%90 for i in lines] 
#lines is in format [[rho,theta]]
#we also mod by 90 as the lines should be orthogonal on page. I.E 90degrees
#deg_lines now contains the degree angles of all lines found in the image. 
candidates_angle = round(np.mean(deg_lines)) # or use the median/mode
#candidates_angle now contatins to the nearest degree the current orientation angle of your doc. Rotate it to the correct angle and you should be good. 



cdst = img.copy() #Just to visualize your lines
if lines is not None:
    for i in range(0, len(lines)):
        rho = lines[i][0][0]
        theta = lines[i][0][1]
        a = math.cos(theta)
        b = math.sin(theta)
        x0 = a * rho
        y0 = b * rho
        pt1 = (int(x0 + 1000*(-b)), int(y0 + 1000*(a)))
        pt2 = (int(x0 - 1000*(-b)), int(y0 - 1000*(a)))
        cv2.line(cdst, pt1, pt2, (0,0,255), 3, cv2.LINE_AA)
plt.imshow(cdst)
plt.show()

第 6 步:旋转图像并运行代码。或者参考cv2/PIL库来旋转图像 你已经这样做了,所以它应该可以工作。

其他文档:

https://docs.opencv.org/3.4/d9/db0/tutorial_hough_lines.html

https://docs.opencv.org/3.4/da/d22/tutorial_py_canny.html

https://docs.opencv.org/4.x/d7/d4d/tutorial_py_thresholding.html

如果您还有任何其他问题,请告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.