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

Recognizing page numbers in scanned PDF image

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

这是一个页面示例

我试过 python + opencv + tesseract 但没有结果,因为我无法检测到数字的正确位置(它可以在任何角落)或者如果 opencv 检测到该位置然后 tesseract 可以'检测文本

这是一个方法

  • 将图像转换为灰度并反转图像
  • 扩张以获得单个轮廓的字母
  • 寻找轮廓
  • 裁剪每个轮廓的 ROI 并放入 Pytesseract
  • 如果结果是数字则保存ROI

转换为灰度并反转图像

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

现在我们扩展以将 letters/contours 连接在一起。这个想法是页码轮廓将与页面上的其他字符分开,即使它可以在任何角落

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

我们从这里找到轮廓,然后提取 ROI。我们将每个 ROI 放入 Pytesseract。如果返回的结果都是数字那么我们已经检测到页码ROI所以我们可以用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

这是 Pytesseract 的结果和提取的 ROI

Page #: 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()