如何用Python提升扫描后模糊纸质文本的可读性?
如何用Python提升扫描后模糊纸质文本的可读性?
完全懂你这种糟心的情况——纸质文本本来就模糊不清,扫描后更是雪上加霜,好不容易凑了Python代码处理,结果3页只剩一页乱码,这谁看了不崩溃😂 咱先把问题拆解清楚,再一步步给你优化方案:
为啥你原来的代码拉胯了?
大概率栽在这几个环节:
- 没给模糊的扫描图做针对性预处理(这是模糊文本识别的核心!)
- PDF转图片时分辨率太低,甚至只默认处理了第一页
- Tesseract OCR的默认配置对模糊文本完全不友好
第一步:先给图像做“美颜预处理”
模糊文本的痛点就是噪点多、笔画虚、背景干扰大,咱先把这些问题解决掉:
import cv2 import numpy as np def preprocess_image(image): # 1. 转灰度图:砍掉彩色干扰,减少计算量 gray = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2GRAY) # 2. 降噪:用中值滤波对付扫描的颗粒噪点,比高斯模糊更适配文本场景 denoised = cv2.medianBlur(gray, 3) # 3. 自适应二值化:专门对付光照不均匀的扫描件,硬把文本和背景分开 # 参数可以自己调:11是块大小,2是常数,数值越大文本越粗 thresh = cv2.adaptiveThreshold(denoised, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) # 4. 形态学膨胀:把模糊的笔画补全,要是文本太粗就换成腐蚀操作(cv2.erode) kernel = np.ones((2,2), np.uint8) processed = cv2.dilate(thresh, kernel, iterations=1) return processed
第二步:把PDF转成高清图,每页都不放过
之前大概率是转图时分辨率不够(默认dpi很低),咱直接拉满分辨率,一次性处理所有页面:
from pdf2image import convert_from_path # 把PDF转成300dpi的高清图片,自动识别所有页面 pages = convert_from_path("你的扫描文件.pdf", dpi=300)
第三步:给Tesseract加“专属配置”
默认的Tesseract对模糊文本识别率极低,咱手动调参数适配:
import pytesseract # 配置说明: # --oem 3:用默认的OCR引擎模式 # --psm 6:假设每页是一个统一的文本块(适合扫描件) # -l chi_sim+eng:同时支持中文和英文,只需要中文就写chi_sim tesseract_config = r'--oem 3 --psm 6 -l chi_sim+eng'
第四步:整合所有步骤,生成多页PDF
这次要把所有页面都处理,再也不会只出一页了:
from reportlab.pdfgen import canvas from reportlab.lib.pagesizes import letter # 创建多页PDF,用A4/letter尺寸都行 output_pdf = canvas.Canvas("优化后的文本.pdf", pagesize=letter) width, height = letter for idx, page in enumerate(pages): # 预处理当前页的图片 processed_img = preprocess_image(page) # 用调过配置的Tesseract识别文本 text = pytesseract.image_to_string(processed_img, config=tesseract_config) # 把识别的文本写到PDF对应页面 output_pdf.setFont("Helvetica", 10) y_position = height - 50 # 从页面顶部50px开始写 for line in text.split('\n'): if y_position < 50: # 写到页底就自动换页 output_pdf.showPage() output_pdf.setFont("Helvetica", 10) y_position = height - 50 output_pdf.drawString(50, y_position, line) y_position -= 15 # 每行间距15px output_pdf.save()
最后给你几个实用小Tips
- 如果文本真的糊到离谱,可以试试用超分辨率模型把图片放大再处理,比如用OpenCV的dnn模块加载预训练的超分模型,不用额外装花里胡哨的库
- 一定要装对Tesseract的语言包!识别中文就装
chi_sim包,不然识别出来全是乱码 - 预处理的参数(比如二值化的块大小、形态学的核大小)可以根据你的实际图片微调,多试两次就能找到最合适的数值




