如何利用Tesseract预处理图像的识别结果为原始图像生成可搜索PDF
实现方案
核心前提
要保证预处理后的黑白图像和原始图像的尺寸、分辨率、像素位置完全一致,不要对预处理图像做任何裁剪、缩放、偏移操作,如果需要做旋转校正,原始图像也要同步执行相同的旋转操作,确保两者坐标完全匹配。
实现逻辑
你之前直接生成PDF的方案是把预处理后的黑白图作为PDF的图像层,现在可以拆分流程:
- 用预处理后的黑白图调用Tesseract,获取带坐标信息的结构化识别结果
- 将原始图像作为PDF的底层背景层
- 按照识别结果的坐标,将透明的文本层叠加到PDF对应位置,既保留原始图像的显示效果,又支持文本搜索、选中
代码实现
首先安装依赖:
pip install pytesseract pillow pymupdf
完整实现代码:
import sys import pytesseract from PIL import Image import fitz # 对应PyMuPDF库 # 你自己的Tesseract配置,和之前保持一致即可 custom_tesseract_config = "" # 你自己的黑白图预处理函数 def create_black_and_white(image, threshold): # 这里保留你原来的预处理逻辑,注意不要修改图像尺寸 pass # 1. 加载原始图像和预处理黑白图 original_img_path = sys.argv[1] original_img = Image.open(original_img_path) black_and_white = create_black_and_white(image=original_img_path, threshold=150) # 校验尺寸一致,避免坐标错位 assert original_img.size == black_and_white.size, "预处理后图像和原图尺寸不匹配,无法对齐坐标" # 2. 获取带坐标的结构化OCR识别结果 ocr_data = pytesseract.image_to_data( black_and_white, config=custom_tesseract_config, output_type=pytesseract.Output.DICT ) # 3. 生成带原始图像背景的可搜索PDF doc = fitz.open() img_width, img_height = original_img.size # 创建和图像同尺寸的PDF页面 page = doc.new_page(width=img_width, height=img_height) # 插入原始图像作为底层背景 page.insert_image( fitz.Rect(0, 0, img_width, img_height), filename=original_img_path ) # 4. 叠加透明可搜索文本层 for i in range(len(ocr_data["text"])): text = ocr_data["text"][i].strip() if not text: continue # 读取当前文本的坐标信息 x = ocr_data["left"][i] y = ocr_data["top"][i] w = ocr_data["width"][i] h = ocr_data["height"][i] # 计算适配的字体大小 font_size = h * 0.9 # 插入透明文本,fill设为None表示文本不可见,仅保留可搜索属性 page.insert_text( (x, y + h * 0.9), # 微调Y坐标适配文本基线,避免偏移 text, fontsize=font_size, fill=None ) # 保存最终PDF doc.save("programme_with_original_background.pdf") doc.close()
注意事项
- 如果识别文本出现偏移,可以调整
insert_text的Y坐标系数,或者改用hOCR格式的识别结果获取更精确的基线坐标 - 如果是多页图像批量处理,循环处理每一页图像,重复上述逻辑添加多个PDF页面即可
内容的提问来源于stack exchange,提问作者Noxx
相关产品推荐
相关产品推荐

