找回密码
 立即注册
首页 业界区 安全 003:RAG 入门-LangChain 读取图片数据

003:RAG 入门-LangChain 读取图片数据

诸婉丽 2 小时前
LangChain 读取图片数据

本文是 refine-rag 系列教程的第三篇,教你如何使用 LangChain 处理图片和 PPT 等多媒体数据。
目录


  • 前言
  • 环境准备
  • 读取图片中的文字(OCR)
  • 读取 PPT 文档
  • 多模态 RAG 的应用场景
  • 常见问题
  • 下一步学习
前言

在前面的文章中,我们学习了如何读取纯文本数据。但在实际应用中,很多重要信息都存储在图片、PPT、扫描件等非文本格式中。比如:

  • 产品宣传图中的文字说明
  • PPT 演示文稿中的内容
  • 扫描的合同和发票
  • 截图中的代码和配置
这些数据如果不能被 RAG 系统处理,就会造成信息的缺失。本文将介绍如何使用 Unstructured 库来处理这些多媒体数据。
环境准备

1. 安装依赖包
  1. # 基础依赖
  2. pip install langchain langchain-community
  3. # Unstructured 完整版(包含图片处理)
  4. pip install "unstructured[all-docs]"
  5. # OCR 依赖(用于图片文字识别)
  6. pip install pdfminer.six
  7. # 如果需要更好的 OCR 效果,可以安装 Tesseract
  8. # macOS: brew install tesseract
  9. # Ubuntu: sudo apt-get install tesseract-ocr
  10. # Windows: 下载安装包 https://github.com/UB-Mannheim/tesseract/wiki
复制代码
2. 安装 LibreOffice(处理 PPT 必需)

Unstructured 处理 Office 文档时需要 LibreOffice 的命令行工具:
  1. # macOS
  2. brew install libreoffice
  3. # Ubuntu/Debian
  4. sudo apt-get update && sudo apt-get install -y libreoffice
  5. # Windows
  6. # 下载安装:https://www.libreoffice.org/download/download/
复制代码
为什么需要 LibreOffice?
Unstructured 会调用 soffice 命令将 PPT/Word/Excel 转换为可解析的格式。如果没有安装,会报错:FileNotFoundError: [Errno 2] No such file or directory: 'soffice'
3. 准备测试数据

准备一些测试文件:

  • 一张包含文字的图片(如截图、海报)
  • 一个 PPT 文件
读取图片中的文字(OCR)

使用 Unstructured 的 OCR 功能提取图片中的文字。
文件名: 01-Unstructured读图.py
  1. from langchain_community.document_loaders import UnstructuredImageLoader
  2. # 图片路径
  3. image_path = "../99-doc-data/黑悟空/黑悟空英文.jpg"
  4. # 创建加载器
  5. loader = UnstructuredImageLoader(image_path)
  6. # 加载并提取文字
  7. data = loader.load()
  8. print(data)
复制代码
输出结果:
  1. Warning: No languages specified, defaulting to English.
  2. [Document(
  3.     metadata={'source': '../99-doc-data/黑悟空/黑悟空英文.jpg'},
  4.     page_content='2\n\nPons\n\nBLACK MYTH. WUKONGY\n\n4'
  5. )]
复制代码
关键点:

  • 语言设置:默认使用英文 OCR,如果是中文图片,识别效果可能不佳
  • OCR 引擎:Unstructured 默认使用 Tesseract,可以通过参数指定其他引擎
  • 图片质量:清晰度越高,识别准确率越高
改进版本(支持中文):
  1. from langchain_community.document_loaders import UnstructuredImageLoader
  2. # 指定中文语言
  3. loader = UnstructuredImageLoader(
  4.     image_path,
  5.     strategy="hi_res",  # 高分辨率模式,识别更准确
  6.     languages=["chi_sim", "eng"]  # 支持简体中文和英文
  7. )
  8. data = loader.load()
  9. print(data[0].page_content)
复制代码
strategy 参数说明:
策略说明适用场景fast快速模式,不使用 OCR图片中没有文字hi_res高分辨率模式,使用 OCR需要提取图片中的文字ocr_only仅使用 OCR扫描件、纯文字图片读取 PPT 文档

PPT 是常见的演示文稿格式,包含文字、图片、图表等多种元素。
文件名: 02-Unstructured读PPT.py
  1. from unstructured.partition.ppt import partition_ppt
  2. from langchain_core.documents import Document
  3. # 解析 PPT 文件
  4. ppt_elements = partition_ppt(filename="../99-doc-data/黑悟空/黑神话悟空.pptx")
  5. print("PPT 内容:")
  6. for element in ppt_elements:
  7.     print("=====分页=====")
  8.     print(element.text)
  9. # 转换为 LangChain 的 Document 格式
  10. documents = [
  11.     Document(
  12.         page_content=element.text,
  13.         metadata={
  14.             "source": "data/黑神话悟空PPT.pptx",
  15.             "page": i,
  16.             "type": str(type(element).__name__)
  17.         }
  18.     )
  19.     for i, element in enumerate(ppt_elements)
  20. ]
  21. # 输出转换后的 Documents
  22. print(f"\n共提取 {len(documents)} 个元素")
  23. for doc in documents[:3]:  # 只打印前 3 个
  24.     print(f"类型: {doc.metadata['type']}")
  25.     print(f"内容: {doc.page_content[:100]}...")
  26.     print("-" * 50)
复制代码
PPT 元素类型:
Unstructured 会将 PPT 解析为不同类型的元素:

  • Title:标题
  • NarrativeText:正文段落
  • ListItem:列表项
  • Table:表格
  • Image:图片(会尝试 OCR)
保留更多元数据:
  1. documents = [
  2.     Document(
  3.         page_content=element.text,
  4.         metadata={
  5.             "source": "data/黑神话悟空PPT.pptx",
  6.             "page": i,
  7.             "type": str(type(element).__name__),
  8.             "category": element.category if hasattr(element, 'category') else None,
  9.             "element_id": element.id if hasattr(element, 'id') else None
  10.         }
  11.     )
  12.     for i, element in enumerate(ppt_elements)
  13. ]
复制代码
处理 PPT 中的图片:
  1. from unstructured.partition.ppt import partition_ppt
  2. # 启用图片推断(会对图片进行 OCR)
  3. ppt_elements = partition_ppt(
  4.     filename="../99-doc-data/黑悟空/黑神话悟空.pptx",
  5.     infer_table_structure=True,  # 推断表格结构
  6.     strategy="hi_res",  # 高分辨率模式
  7.     extract_images_in_pdf=True  # 提取图片
  8. )
复制代码
多模态 RAG 的应用场景

处理图片和 PPT 数据后,可以构建更强大的多模态 RAG 系统:
1. 企业知识库
  1. # 场景:公司有大量 PPT 培训资料
  2. from langchain_community.document_loaders import DirectoryLoader
  3. from unstructured.partition.ppt import partition_ppt
  4. # 批量加载所有 PPT
  5. loader = DirectoryLoader(
  6.     "./training_materials/",
  7.     glob="**/*.pptx",
  8.     show_progress=True
  9. )
  10. # 构建知识库
  11. documents = []
  12. for doc in loader.load():
  13.     ppt_elements = partition_ppt(filename=doc.metadata['source'])
  14.     for element in ppt_elements:
  15.         documents.append(Document(
  16.             page_content=element.text,
  17.             metadata={"source": doc.metadata['source']}
  18.         ))
  19. # 后续可以进行向量化和检索
复制代码
2. 产品文档助手
  1. # 场景:产品手册包含大量截图和说明
  2. from langchain_community.document_loaders import UnstructuredImageLoader
  3. # 处理产品截图
  4. screenshots = ["feature1.png", "feature2.png", "feature3.png"]
  5. docs = []
  6. for img in screenshots:
  7.     loader = UnstructuredImageLoader(
  8.         img,
  9.         strategy="hi_res",
  10.         languages=["chi_sim", "eng"]
  11.     )
  12.     docs.extend(loader.load())
  13. # 结合文本文档构建完整知识库
复制代码
3. 合同和发票处理
  1. # 场景:扫描的合同需要提取关键信息
  2. from langchain_community.document_loaders import UnstructuredImageLoader
  3. # 处理扫描件
  4. loader = UnstructuredImageLoader(
  5.     "contract_scan.jpg",
  6.     strategy="ocr_only",  # 纯 OCR 模式
  7.     languages=["chi_sim"]
  8. )
  9. contract_docs = loader.load()
  10. # 提取关键信息(可以结合 LLM)
  11. from langchain_openai import ChatOpenAI
  12. llm = ChatOpenAI()
  13. result = llm.invoke(f"从以下合同中提取甲方、乙方、金额:\n{contract_docs[0].page_content}")
复制代码
4. 学术论文分析
  1. # 场景:论文中的图表和公式
  2. # 可以结合多模态模型(如 GPT-4V)进行更深入的理解
  3. from langchain_community.document_loaders import UnstructuredImageLoader
  4. # 提取论文中的图表
  5. loader = UnstructuredImageLoader(
  6.     "paper_figure.png",
  7.     strategy="hi_res"
  8. )
  9. figure_docs = loader.load()
  10. # 使用多模态模型理解图表
  11. # (需要支持图片输入的模型)
复制代码
常见问题

1. LibreOffice 未安装
  1. # 错误:FileNotFoundError: [Errno 2] No such file or directory: 'soffice'
  2. # 解决:安装 LibreOffice
  3. # macOS
  4. brew install libreoffice
  5. # Ubuntu
  6. sudo apt-get install libreoffice
复制代码
2. OCR 识别效果差

问题原因:

  • 图片分辨率太低
  • 文字太小或模糊
  • 语言设置不正确
解决方案:
  1. # 1. 使用高分辨率模式
  2. loader = UnstructuredImageLoader(
  3.     image_path,
  4.     strategy="hi_res"  # 而不是 "fast"
  5. )
  6. # 2. 指定正确的语言
  7. loader = UnstructuredImageLoader(
  8.     image_path,
  9.     languages=["chi_sim", "eng"]  # 中英文混合
  10. )
  11. # 3. 预处理图片(提高对比度、去噪等)
  12. from PIL import Image, ImageEnhance
  13. img = Image.open(image_path)
  14. enhancer = ImageEnhance.Contrast(img)
  15. img = enhancer.enhance(2.0)  # 增强对比度
  16. img.save("enhanced.jpg")
  17. # 再进行 OCR
  18. loader = UnstructuredImageLoader("enhanced.jpg")
复制代码
3. PPT 解析速度慢
  1. # 问题:大型 PPT 文件解析很慢
  2. # 解决:跳过不必要的处理
  3. ppt_elements = partition_ppt(
  4.     filename="large.pptx",
  5.     include_page_breaks=False,  # 不包含分页符
  6.     infer_table_structure=False,  # 不推断表格结构(如果不需要)
  7.     extract_images_in_pdf=False  # 不提取图片(如果不需要)
  8. )
复制代码
4. 中文 OCR 支持
  1. # 如果使用 Tesseract,需要下载中文语言包
  2. # macOS
  3. brew install tesseract-lang
  4. # Ubuntu
  5. sudo apt-get install tesseract-ocr-chi-sim
  6. # 验证安装
  7. tesseract --list-langs
  8. # 应该能看到 chi_sim(简体中文)
复制代码
5. 内存占用过高
  1. # 问题:处理大量图片时内存不足
  2. # 解决:分批处理
  3. def process_images_in_batches(image_paths, batch_size=10):
  4.     results = []
  5.     for i in range(0, len(image_paths), batch_size):
  6.         batch = image_paths[i:i+batch_size]
  7.         for img_path in batch:
  8.             loader = UnstructuredImageLoader(img_path)
  9.             results.extend(loader.load())
  10.         # 可以在这里保存中间结果
  11.     return results
  12. # 使用
  13. all_docs = process_images_in_batches(image_list, batch_size=10)
复制代码
进阶技巧

1. 结合多模态大模型

对于复杂的图片(如图表、流程图),纯 OCR 可能不够:
  1. # 使用支持图片输入的模型(如 GPT-4V、Claude 3)
  2. from langchain_openai import ChatOpenAI
  3. import base64
  4. def encode_image(image_path):
  5.     with open(image_path, "rb") as image_file:
  6.         return base64.b64encode(image_file.read()).decode('utf-8')
  7. # 创建多模态消息
  8. base64_image = encode_image("chart.png")
  9. llm = ChatOpenAI(model="gpt-4-vision-preview")
  10. response = llm.invoke([
  11.     {"type": "text", "text": "请描述这张图表的内容"},
  12.     {"type": "image_url", "image_url": f"data:image/png;base64,{base64_image}"}
  13. ])
  14. print(response.content)
复制代码
2. 图片预处理流程
  1. from PIL import Image, ImageEnhance, ImageFilter
  2. def preprocess_image(image_path, output_path):
  3.     """图片预处理,提高 OCR 准确率"""
  4.     img = Image.open(image_path)
  5.    
  6.     # 1. 转为灰度图
  7.     img = img.convert('L')
  8.    
  9.     # 2. 增强对比度
  10.     enhancer = ImageEnhance.Contrast(img)
  11.     img = enhancer.enhance(2.0)
  12.    
  13.     # 3. 锐化
  14.     img = img.filter(ImageFilter.SHARPEN)
  15.    
  16.     # 4. 调整大小(如果太小)
  17.     if img.width < 1000:
  18.         scale = 1000 / img.width
  19.         new_size = (int(img.width * scale), int(img.height * scale))
  20.         img = img.resize(new_size, Image.LANCZOS)
  21.    
  22.     img.save(output_path)
  23.     return output_path
  24. # 使用
  25. enhanced_path = preprocess_image("low_quality.jpg", "enhanced.jpg")
  26. loader = UnstructuredImageLoader(enhanced_path)
  27. docs = loader.load()
复制代码
3. 构建混合文档索引
  1. from langchain_community.document_loaders import (
  2.     TextLoader,
  3.     UnstructuredImageLoader,
  4.     DirectoryLoader
  5. )
  6. from unstructured.partition.ppt import partition_ppt
  7. def load_mixed_documents(directory):
  8.     """加载目录下的所有文档(文本、图片、PPT)"""
  9.     all_docs = []
  10.    
  11.     # 1. 加载文本文件
  12.     text_loader = DirectoryLoader(
  13.         directory,
  14.         glob="**/*.txt",
  15.         loader_cls=TextLoader,
  16.         loader_kwargs={'encoding': 'utf-8'}
  17.     )
  18.     all_docs.extend(text_loader.load())
  19.    
  20.     # 2. 加载图片
  21.     image_loader = DirectoryLoader(
  22.         directory,
  23.         glob="**/*.{jpg,png,jpeg}",
  24.         loader_cls=UnstructuredImageLoader
  25.     )
  26.     all_docs.extend(image_loader.load())
  27.    
  28.     # 3. 加载 PPT
  29.     import glob
  30.     for ppt_file in glob.glob(f"{directory}/**/*.pptx", recursive=True):
  31.         ppt_elements = partition_ppt(filename=ppt_file)
  32.         for element in ppt_elements:
  33.             all_docs.append(Document(
  34.                 page_content=element.text,
  35.                 metadata={"source": ppt_file, "type": "ppt"}
  36.             ))
  37.    
  38.     return all_docs
  39. # 使用
  40. docs = load_mixed_documents("./knowledge_base/")
  41. print(f"共加载 {len(docs)} 个文档")
复制代码
学习路径


  • 简易RAG 学习
  • LCEL 语法学习
  • LangChain 读取数据

    • LangChain 读取文本数据
    • LangChain 读取图片数据
    • LangChain 读取 PDF 数据
    • LangChain 读取表格数据

  • 文本切块
  • 向量嵌入
  • 向量存储
  • 检索前处理
  • 索引优化
  • 检索后处理
  • 响应生成
  • 系统评估
项目地址

本文所有代码示例都在 GitHub 开源:
https://github.com/zonezoen/refine-rag
欢迎 Star 和 Fork,一起学习 RAG 技术!

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册