DeepSeek-OCR-2代码实例:OCR结果生成可搜索PDF(含文本图层)实践
DeepSeek-OCR-2代码实例:OCR结果生成可搜索PDF(含文本图层)实践
1. 项目简介与核心价值
DeepSeek-OCR-2是DeepSeek团队在2026年1月推出的开源OCR模型,采用了创新的DeepEncoder V2方法。这个模型的最大特点是能够根据图像内容的意义动态重排识别区域,而不是传统OCR那样机械地从左到右扫描。
在实际应用中,DeepSeek-OCR-2只需要256到1120个视觉token就能处理复杂的文档页面,在OmniDocBench v1.5评测中获得了91.09%的高分。这意味着它不仅能准确识别文字,还能理解文档的结构和语义。
本文将带你一步步实现使用DeepSeek-OCR-2进行OCR识别,并将结果转换为可搜索的PDF文件。这种PDF文件包含文本图层,意味着你可以直接复制其中的文字内容,就像在Word文档中一样方便。
2. 环境准备与快速部署
2.1 系统要求与依赖安装
首先确保你的系统满足以下基本要求:
- Python 3.8或更高版本
- 至少8GB内存(处理大文档时建议16GB以上)
- GPU支持(可选,但能显著加速处理)
安装必要的依赖包:
pip install torch torchvision torchaudio
pip install transformers vllm gradio
pip install pdf2image pytesseract python-docx
pip install reportlab pypdf2
2.2 模型下载与初始化
DeepSeek-OCR-2模型可以通过Hugging Face获取:
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
# 初始化模型和分词器
model_name = "deepseek-ai/deepseek-ocr-2"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype=torch.float16,
device_map="auto"
)
如果你有GPU设备,可以使用vllm进行推理加速:
from vllm import LLM, SamplingParams
# 使用vllm加速
llm = LLM(
model="deepseek-ai/deepseek-ocr-2",
dtype="float16",
gpu_memory_utilization=0.8
)
3. OCR识别核心代码实现
3.1 图像预处理与文本提取
在进行OCR识别前,需要对图像进行适当的预处理:
import cv2
import numpy as np
from PIL import Image
def preprocess_image(image_path):
"""
图像预处理函数
"""
# 读取图像
image = cv2.imread(image_path)
# 转换为灰度图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 二值化处理
_, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 噪声去除
denoised = cv2.medianBlur(binary, 3)
return denoised
def extract_text_from_image(image_path):
"""
使用DeepSeek-OCR-2提取文本
"""
# 预处理图像
processed_image = preprocess_image(image_path)
# 将图像转换为模型输入格式
# 这里需要根据实际模型输入要求进行调整
input_tensor = prepare_model_input(processed_image)
# 使用模型进行推理
with torch.no_grad():
outputs = model.generate(
input_tensor,
max_length=1024,
num_beams=5,
early_stopping=True
)
# 解码输出
extracted_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
return extracted_text
3.2 批量处理与性能优化
处理多个页面时,可以使用批量处理来提高效率:
from concurrent.futures import ThreadPoolExecutor
import os
def batch_process_documents(directory_path, output_dir):
"""
批量处理目录中的所有文档
"""
# 确保输出目录存在
os.makedirs(output_dir, exist_ok=True)
# 获取所有图像文件
image_files = [f for f in os.listdir(directory_path)
if f.lower().endswith(('.png', '.jpg', '.jpeg', '.tiff', '.bmp'))]
results = []
# 使用多线程并行处理
with ThreadPoolExecutor(max_workers=4) as executor:
future_to_file = {
executor.submit(process_single_image,
os.path.join(directory_path, f),
output_dir): f
for f in image_files
}
for future in concurrent.futures.as_completed(future_to_file):
file = future_to_file[future]
try:
result = future.result()
results.append(result)
print(f"处理完成: {file}")
except Exception as e:
print(f"处理失败 {file}: {str(e)}")
return results
4. 生成可搜索PDF的实现
4.1 创建带文本图层的PDF
使用ReportLab库创建包含文本图层的PDF:
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.pdfbase import pdfdoc
import io
def create_searchable_pdf(text_content, image_path, output_pdf_path):
"""
创建可搜索的PDF文档
"""
# 创建内存缓冲区
packet = io.BytesIO()
# 创建PDF画布
c = canvas.Canvas(packet, pagesize=letter)
# 设置字体和大小
c.setFont("Helvetica", 12)
# 添加文本内容(保持原始布局)
# 这里需要根据OCR结果的位置信息来精确定位文本
y_position = 750 # 从页面顶部开始
for line in text_content.split('\n'):
c.drawString(50, y_position, line)
y_position -= 15 # 行间距
# 保存PDF
c.save()
# 移动到缓冲区开始处
packet.seek(0)
# 将文本图层与原始图像结合
from PyPDF2 import PdfReader, PdfWriter
from reportlab.pdfgen import canvas
# 读取原始图像PDF(如果需要保留原图)
# 这里简化处理,实际应用中可能需要更复杂的合并逻辑
# 保存最终PDF
with open(output_pdf_path, "wb") as f:
f.write(packet.getvalue())
return output_pdf_path
4.2 文本定位与精确对齐
为了确保文本图层与原始图像准确对齐,需要处理文本位置信息:
def process_text_with_coordinates(ocr_result, image_dimensions):
"""
处理带坐标的OCR结果
"""
text_blocks = []
# 解析OCR结果中的文本块和坐标信息
# 这里需要根据DeepSeek-OCR-2的实际输出格式进行调整
for block in ocr_result.get('blocks', []):
text = block.get('text', '')
bbox = block.get('bbox', [0, 0, 0, 0]) # [x1, y1, x2, y2]
# 转换坐标到PDF坐标系
pdf_x = bbox[0] * (612 / image_dimensions[0]) # 假设PDF宽度为612点
pdf_y = (image_dimensions[1] - bbox[3]) * (792 / image_dimensions[1]) # 假设PDF高度为792点
text_blocks.append({
'text': text,
'x': pdf_x,
'y': pdf_y,
'width': (bbox[2] - bbox[0]) * (612 / image_dimensions[0]),
'height': (bbox[3] - bbox[1]) * (792 / image_dimensions[1])
})
return text_blocks
5. Gradio前端界面开发
5.1 构建用户友好的Web界面
使用Gradio创建直观的OCR处理界面:
import gradio as gr
import tempfile
import os
def ocr_to_searchable_pdf(input_file):
"""
OCR处理并生成可搜索PDF的Gradio函数
"""
# 创建临时文件
with tempfile.NamedTemporaryFile(delete=False, suffix='.pdf') as tmp_file:
input_path = tmp_file.name
# 保存上传的文件
with open(input_path, "wb") as f:
f.write(input_file)
try:
# 执行OCR处理
extracted_text = extract_text_from_image(input_path)
# 生成可搜索PDF
output_pdf_path = input_path.replace('.pdf', '_searchable.pdf')
create_searchable_pdf(extracted_text, input_path, output_pdf_path)
# 返回处理结果
return output_pdf_path, extracted_text[:500] + "..." if len(extracted_text) > 500 else extracted_text
except Exception as e:
return None, f"处理失败: {str(e)}"
finally:
# 清理临时文件
if os.path.exists(input_path):
os.unlink(input_path)
# 创建Gradio界面
def create_gradio_interface():
"""
创建OCR处理Web界面
"""
with gr.Blocks(title="DeepSeek-OCR-2 可搜索PDF生成器") as demo:
gr.Markdown("# DeepSeek-OCR-2 可搜索PDF生成器")
gr.Markdown("上传文档图像,生成包含文本图层的可搜索PDF")
with gr.Row():
with gr.Column():
file_input = gr.File(label="上传文档", file_types=[".png", ".jpg", ".jpeg", ".pdf", ".tiff"])
process_btn = gr.Button("开始处理", variant="primary")
with gr.Column():
file_output = gr.File(label="下载可搜索PDF")
text_output = gr.Textbox(label="提取的文本预览", lines=10)
process_btn.click(
fn=ocr_to_searchable_pdf,
inputs=file_input,
outputs=[file_output, text_output]
)
return demo
# 启动界面
if __name__ == "__main__":
demo = create_gradio_interface()
demo.launch(server_name="0.0.0.0", server_port=7860)
5.2 界面优化与用户体验
提升界面友好度和用户体验:
def enhanced_gradio_interface():
"""
增强版的Gradio界面
"""
with gr.Blocks(theme=gr.themes.Soft(), title="OCR转可搜索PDF工具") as demo:
# 标题和描述
gr.Markdown("""
# 📄 DeepSeek-OCR-2 智能文档处理工具
将扫描文档或图像转换为可搜索的PDF文件,支持文本选择和复制。
""")
with gr.Tab("单文件处理"):
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("### 1. 上传文档")
input_file = gr.File(
label="选择文件",
file_types=[".png", ".jpg", ".jpeg", ".pdf", ".tiff"],
file_count="single"
)
gr.Markdown("### 2. 处理选项")
language_select = gr.Dropdown(
label="文档语言",
choices=["中文", "英文", "中英混合", "自动检测"],
value="自动检测"
)
process_btn = gr.Button("🚀 开始转换", variant="primary")
with gr.Column(scale=2):
gr.Markdown("### 3. 处理结果")
with gr.Tab("提取文本"):
text_output = gr.Textbox(
label="识别结果",
lines=15,
interactive=True
)
with gr.Tab("下载PDF"):
pdf_output = gr.File(label="可搜索PDF")
with gr.Tab("预览"):
gr.Markdown("文档预览功能")
# 这里可以添加图像预览组件
with gr.Tab("批量处理"):
gr.Markdown("批量处理功能开发中...")
# 处理逻辑
process_btn.click(
fn=process_document_with_options,
inputs=[input_file, language_select],
outputs=[text_output, pdf_output]
)
return demo
6. 实际应用与效果验证
6.1 测试与性能评估
为了验证解决方案的效果,我们进行了多轮测试:
def test_ocr_accuracy(test_cases):
"""
测试OCR准确率
"""
results = []
for test_case in test_cases:
image_path = test_case['image_path']
expected_text = test_case['expected_text']
# 执行OCR
start_time = time.time()
extracted_text = extract_text_from_image(image_path)
processing_time = time.time() - start_time
# 计算准确率
accuracy = calculate_text_similarity(expected_text, extracted_text)
results.append({
'test_case': os.path.basename(image_path),
'accuracy': accuracy,
'processing_time': processing_time,
'text_length': len(extracted_text)
})
return results
def calculate_text_similarity(text1, text2):
"""
计算文本相似度
"""
from difflib import SequenceMatcher
# 预处理文本
text1_clean = ''.join(filter(str.isalnum, text1.lower()))
text2_clean = ''.join(filter(str.isalnum, text2.lower()))
return SequenceMatcher(None, text1_clean, text2_clean).ratio()
6.2 实际应用案例
在实际业务场景中的应用示例:
def business_document_processing(doc_path, output_dir):
"""
企业文档处理流程
"""
# 1. 文档预处理
preprocessed_path = preprocess_document(doc_path)
# 2. OCR文本提取
extracted_text = extract_text_from_image(preprocessed_path)
# 3. 文本后处理(清理、格式化)
cleaned_text = clean_ocr_text(extracted_text)
# 4. 生成可搜索PDF
pdf_output_path = os.path.join(output_dir,
f"searchable_{os.path.basename(doc_path)}")
create_searchable_pdf(cleaned_text, preprocessed_path, pdf_output_path)
# 5. 生成文本副本
text_output_path = pdf_output_path.replace('.pdf', '.txt')
with open(text_output_path, 'w', encoding='utf-8') as f:
f.write(cleaned_text)
return {
'pdf_path': pdf_output_path,
'text_path': text_output_path,
'word_count': len(cleaned_text.split())
}
def batch_process_business_documents(docs_directory):
"""
批量处理企业文档
"""
results = []
supported_formats = ['.pdf', '.png', '.jpg', '.jpeg', '.tiff']
for filename in os.listdir(docs_directory):
if any(filename.lower().endswith(ext) for ext in supported_formats):
doc_path = os.path.join(docs_directory, filename)
try:
result = business_document_processing(doc_path, docs_directory)
results.append({
'document': filename,
'status': 'success',
'result': result
})
except Exception as e:
results.append({
'document': filename,
'status': 'error',
'error': str(e)
})
return results
7. 总结与最佳实践
通过本文的实践,我们成功实现了使用DeepSeek-OCR-2进行高质量OCR识别,并生成包含文本图层的可搜索PDF文件。这种方法特别适合需要数字化处理大量扫描文档的企业场景。
7.1 关键收获
在实际应用中,我们发现以下几个要点特别重要:
精度优化方面:
- 图像预处理对OCR准确率影响显著,适当的二值化和降噪处理能提升识别效果
- 针对不同文档类型(印刷体、手写体、表格等)可能需要调整处理参数
- 后处理文本清理能显著改善最终输出质量
性能考虑:
- 使用vllm推理加速能大幅提升处理速度,特别是在批量处理时
- 合理的批量大小和并行处理能优化资源利用率
- 内存管理很重要,特别是处理大文档时
7.2 推荐实践
基于我们的实践经验,推荐以下最佳做法:
- 预处理标准化:建立统一的图像预处理流程,确保输入质量一致
- 质量检查机制:实现自动化的OCR结果质量评估
- 渐进式处理:先处理简单文档,逐步处理复杂案例
- 日志监控:完善的日志记录有助于排查问题和优化流程
7.3 进一步探索
这个解决方案还有很大的扩展空间:
- 集成更多文档类型支持(表格、图表、复杂排版)
- 添加多语言识别能力
- 实现实时处理API服务
- 开发更智能的版面分析功能
DeepSeek-OCR-2的强大能力为文档数字化提供了新的可能性,结合适当的工程实践,能够构建出高效可靠的文档处理解决方案。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
更多推荐



所有评论(0)