python - 识别扫描的 PDF 图像中的页码
问题描述
我有很多 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
现在我们扩张以将字母/轮廓连接在一起。这个想法是页码轮廓将与页面上的其他字符分开,即使它可能位于任何角落
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
页码: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()
推荐阅读
- ios - 更改 UITableView 中一些选定的表格视图单元格文本的颜色
- c - C 最低标准要求
- android - 一段时间后如何以编程方式更改 ImageView 的图像源
- r - 使用变量作为开始和结束时间的子集 xts 对象
- javascript - 如何在foreach中将数据传递给angularjs foreach
- makefile - 当目标名称不是文件名时如何建立make依赖
- sql - 如果没有 CASE 语句的值为 0,则返回 1
- java - 我如何从路径中获取特定目录的子路径?
- c# - 如何调用具有不同对象作为参数类型的方法
- html - Whatsapp 分享按钮不起作用,如何解决?