处理 PDF 中的图像
处理 PDF 中的图像,核心思路是“提取 + 理解”:先把图像从 PDF 里“挖”出来,再用专门的技术让 AI “看懂”它。
对于你的 my_ai_platform 项目,关键在于如何将图像里的信息,无缝融入你现有的 RAG 文本检索流程中。主要有三种主流方案,难度和效果依次递进。
方案一:OCR 文字提取(最基础)
这适用于包含文字的图片,比如扫描的合同页或带有文字说明的截图。
核心流程:从 PDF 中提取图片 → 进行图像预处理 → OCR 识别文字 → 将识别出的文字加入向量库。
- 原理:把图像“翻译”成文字,然后像处理普通文本一样处理它。
- 技术栈:
- PyMuPDF (fitz):用于解析 PDF 并高效提取其中的图像。
- OpenCV:用于图像预处理(如二值化、去噪),可显著提升 OCR 准确率。
- PaddleOCR / Tesseract:用于光学字符识别(OCR)。PaddleOCR 对中文等复杂场景效果更好。
代码示例(基于 PyMuPDF 和 Tesseract):
import fitz # PyMuPDF
import cv2
import pytesseract
import numpy as np
from PIL import Image
def extract_and_ocr_images(pdf_path):
doc = fitz.open(pdf_path)
all_ocr_text = []
for page_num in range(len(doc)):
page = doc.load_page(page_num)
# 1. 提取图像
image_list = page.get_images(full=True)
for img_index, img in enumerate(image_list):
xref = img[0]
base_image = doc.extract_image(xref)
image_bytes = base_image["image"]
# 将字节转为 PIL Image
image = Image.open(io.BytesIO(image_bytes))
# 2. 图像预处理
open_cv_image = np.array(image)
gray = cv2.cvtColor(open_cv_image, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 3. OCR 识别
text = pytesseract.image_to_string(thresh, lang='chi_sim+eng')
all_ocr_text.append(text)
return "\n".join(all_ocr_text)
对于整个页面都是图像的扫描件 PDF,更直接的做法是先用
pdf2image将每一页渲染成图片,再进行 OCR。
方案二:多模态模型生成描述(效果好,更智能)
这适用于包含图表的图片(如柱状图、流程图、数据可视化图表)或需要理解视觉关系的场景。
核心流程:提取图像 → 用多模态大模型(VLM)“看图说话”,生成一段描述文本 → 将描述文本加入向量库。
- 原理:让 AI 直接“看”图,然后用自然语言总结出图里的信息,比如“这张图展示了2023年各季度销售额的增长趋势”。
- 技术栈:
- 闭源方案:GPT-4V (Vision)、Gemini Vision、Claude 3 等。
- 开源/本地方案:Qwen-VL、CogVLM、LLaVA 等。
- 优势:能理解图像的深层含义,而不仅仅是提取文字。
代码示例(使用 OpenAI 兼容的视觉模型):
from openai import OpenAI
import base64
def describe_image_with_vlm(image_path):
client = OpenAI(api_key="YOUR_API_KEY", base_url="YOUR_VLM_ENDPOINT")
# 将图像转为 Base64
with open(image_path, "rb") as image_file:
base64_image = base64.b64encode(image_file.read()).decode('utf-8')
response = client.chat.completions.create(
model="gpt-4-vision-preview", # 或其他 VLM 模型
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "请详细描述这张图片的内容。"},
{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{base64_image}"}}
]
}
]
)
return response.choices[0].message.content
方案三:端到端多模态 RAG(最前沿,信息无损)
这代表了一种更前沿的思路,即不完全依赖文本提取。
核心流程:将 PDF 页面直接作为图像处理 → 使用视觉 embedding 模型(如 CLIP)直接为整个页面生成向量 → 检索时,用同样的模型将用户问题也转为向量,进行相似度匹配。
- 原理:跳过“图像→文字”的转换步骤,直接在“图像”和“问题”的向量空间里做匹配,避免了 OCR 或 VLM 描述可能带来的信息丢失。
- 技术栈:多模态 embedding 模型(如 CLIP、BridgeTower),专用的向量数据库。
这种方案对基础设施要求更高,但它能完整保留表格、图表、排版甚至手写批注等所有视觉信息,是未来的一个发展方向。
🛠️ 给你的集成建议
综合你的项目现状,我建议采用分阶段、渐进式的集成策略:
第一阶段:快速集成 OCR(解决“有没有”)
- 安装依赖:
pip install pymupdf opencv-python pytesseract pdf2image - 安装系统依赖:
- 修改
DocumentUploadService:在upload_and_update_index方法中,当PDFValidator判定文件为扫描件或含图像时,调用extract_and_ocr_images提取图像文字,并将结果作为一个特殊“文档”存入向量库。
第二阶段:引入 VLM 增强(解决“好不好”)
- 选择并部署一个 VLM:可以使用阿里云百炼等平台提供的 API 服务,或在本地部署 Qwen-VL 等开源模型。
- 在图像处理流程中加入“描述生成”:对提取出的重要图像(如尺寸较大、位于页面中心的),调用 VLM 生成描述,再将描述文本存入向量库。
- 建立“图像描述”的元数据:在存入向量库时,标记该文本块类型为
image_description,便于后续检索和分析。
💎 总结
| 方案 | 核心任务 | 适用场景 | 优缺点 |
|---|---|---|---|
| OCR 文字提取 | 把图像里的文字“抠”出来 | 文字型图片、扫描件 | 简单直接,但会丢失排版、图表等视觉信息 |
| VLM 生成描述 | 让 AI “看图说话” | 图表、流程图、信息图 | 理解语义,但依赖模型能力,有成本 |
| 端到端多模态 RAG | 直接用向量比较图像 | 需要保留完整视觉信息的场景 | 信息无损,但技术更前沿,实现复杂 |
这三种方案并非互斥,你可以根据文档类型和业务场景组合使用,构建一个更强大的多模态 RAG 系统。
本作品采用《CC 协议》,转载必须注明作者和本文链接
关于 LearnKu
推荐文章: