识别扫描的PDF图像中的页码

时间:2019-08-14 09:16:45

标签: python opencv image-processing ocr tesseract

我有很多PDF,这些PDF基本上是扫描的文档或书籍,因此每个PDF页面都有两个扫描的图像,因此我必须将这些页面分开并根据打印在页面上的页数进行组织。分页不是问题(我正在使用mutool海报),问题是:“如何从页面的PDF部分(图像)中检测页码?

这是一个页面示例

enter image description here

我尝试使用python + opencv + tesseract,但没有结果,因为我无法检测到数字的正确位置(可以在任何角落),或者如果opencv检测到该位置,则tesseract无法检测到文本< / p>

2 个答案:

答案 0 :(得分:1)

这是一种方法

  • 将图像转换为灰度并反转图像
  • 扩张以获得单个轮廓的字母
  • 找到轮廓
  • 裁剪每个轮廓的ROI并放入Pytesseract
  • 如果结果为数字,则可以节省投资回报率

转换为灰度并反转图像

image = cv2.imread('2.png')
original = image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = 255 - gray

enter image description here

现在,我们将字母/轮廓扩展到一起。这样的想法是,即使页面编号轮廓可以在任何角落,也可以与页面上的其他字符分开

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
dilate = cv2.dilate(gray, kernel, iterations=4)

enter image description here

从这里我们找到轮廓,然后提取ROI。我们将每个ROI投入Pytesseract。如果返回的结果是所有数字,则表明我们已检测到页码投资回报率,因此可以使用Numpy切片将其保存

image_number = 0
for c in cnts:
    x,y,w,h = cv2.boundingRect(c)
    ROI = original[y:y+h, x:x+w]
    data = pytesseract.image_to_string(ROI, lang='eng', config='--psm 10')
    if data.isdigit():
        print('Page #: ', data)
        cv2.imwrite("ROI_{}.png".format(image_number), ROI)
        image_number += 1

enter image description here

这是Pytesseract的结果和提取的ROI

enter image description here

  

页面#:110

完整代码

import cv2
import pytesseract

pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"

image = cv2.imread('2.png')
original = image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = 255 - gray

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
dilate = cv2.dilate(gray, kernel, iterations=4)

cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

image_number = 0
for c in cnts:
    x,y,w,h = cv2.boundingRect(c)
    ROI = original[y:y+h, x:x+w]
    data = pytesseract.image_to_string(ROI, lang='eng', config='--psm 10')
    if data.isdigit():
        print('Page #: ', data)
        cv2.imwrite("ROI_{}.png".format(image_number), ROI)
        image_number += 1

cv2.imshow('gray', gray)
cv2.imshow('dilate', dilate)
cv2.imshow('original', original)
cv2.waitKey()

答案 1 :(得分:0)

在您的问题中,opencv检测到位置,但是tesseract无法读取文本,这是正确的吗? 也许,您没有放置正确的参数或边界框。 您使用什么opencv函数检测位置? tesseract参数是什么? 我将对页面进行除角以外的遮罩,并在此“角”图像上使用tesseract。您的噪音会减少。