DeepSeek-OCR-2快速上手:Chrome插件联动OCR WebUI实现网页截图识别
DeepSeek-OCR-2快速上手:Chrome插件联动OCR WebUI实现网页截图识别
1. 引言:当网页截图遇到智能OCR
你有没有遇到过这样的情况?在网上看到一篇技术文章,里面有段代码截图特别有用,你想复制下来,但图片里的文字没法直接选中。或者浏览产品文档时,发现一个重要的表格截图,想要提取里面的数据,却只能手动一个字一个字地敲。
以前遇到这种问题,要么用传统的OCR工具,识别率不高还麻烦;要么就只能手动输入,费时费力。现在有了DeepSeek-OCR-2,这个问题有了全新的解决方案。
DeepSeek-OCR-2是DeepSeek在2026年初发布的开源OCR模型,它采用了一种创新的方法——让AI根据图像的含义动态重排图像的各个部分,而不是机械地从左到右扫描。这意味着它能更好地理解文档的结构和内容,识别准确率大幅提升。
更棒的是,这个模型只需要256到1120个视觉Token就能覆盖复杂的文档页面,在OmniDocBench v1.5评测中综合得分达到了91.09%。今天我要分享的,就是如何快速上手这个强大的OCR工具,并且通过Chrome插件和WebUI的联动,实现网页截图的智能识别。
2. 环境准备与快速部署
2.1 系统要求与依赖安装
在开始之前,我们先看看需要准备什么。DeepSeek-OCR-2的部署相对简单,但有几个前提条件需要满足:
- 操作系统:推荐使用Ubuntu 20.04或更高版本,当然其他Linux发行版也可以
- Python版本:Python 3.8或更高版本
- GPU支持:虽然CPU也能运行,但为了获得更好的性能,建议使用支持CUDA的NVIDIA GPU
- 内存要求:至少16GB RAM,如果处理大文档建议32GB以上
首先,我们创建一个新的虚拟环境并安装基础依赖:
# 创建并激活虚拟环境 python -m venv deepseek-ocr-env source deepseek-ocr-env/bin/activate # 安装PyTorch(根据你的CUDA版本选择) pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 安装其他必要依赖 pip install transformers gradio vllm pillow requests2.2 模型下载与配置
DeepSeek-OCR-2的模型可以从Hugging Face获取。这里我们使用vllm进行推理加速,它能显著提升模型的响应速度。
# 下载并配置模型 from vllm import LLM, SamplingParams # 初始化模型 llm = LLM( model="deepseek-ai/DeepSeek-OCR-2", tensor_parallel_size=1, # 根据你的GPU数量调整 gpu_memory_utilization=0.8, max_model_len=4096 ) # 创建采样参数 sampling_params = SamplingParams( temperature=0.1, top_p=0.9, max_tokens=2048 )如果你遇到网络问题或者想离线使用,也可以先下载模型到本地:
# 使用git-lfs下载模型 git lfs install git clone https://huggingface.co/deepseek-ai/DeepSeek-OCR-2 # 或者使用transformers直接加载 from transformers import AutoModelForCausalLM, AutoTokenizer model = AutoModelForCausalLM.from_pretrained( "./DeepSeek-OCR-2", device_map="auto" ) tokenizer = AutoTokenizer.from_pretrained("./DeepSeek-OCR-2")3. 搭建OCR WebUI界面
3.1 创建Gradio前端应用
Gradio是一个简单易用的Web界面框架,特别适合快速搭建机器学习应用的演示界面。我们来创建一个基本的OCR WebUI:
import gradio as gr from PIL import Image import io import base64 def ocr_inference(image): """处理上传的图片并进行OCR识别""" try: # 将图片转换为base64格式 buffered = io.BytesIO() image.save(buffered, format="PNG") img_str = base64.b64encode(buffered.getvalue()).decode() # 构建提示词 prompt = f"<image>{img_str}</image>\n请识别图片中的文字内容:" # 使用vllm进行推理 outputs = llm.generate([prompt], sampling_params) result = outputs[0].outputs[0].text return result except Exception as e: return f"识别失败:{str(e)}" def process_pdf(pdf_file): """处理PDF文件(多页)""" # 这里简化处理,实际需要将PDF转换为图片 # 可以使用pdf2image库 return "PDF处理功能待完善,当前版本主要支持图片识别" # 创建Gradio界面 with gr.Blocks(title="DeepSeek-OCR-2 WebUI", theme=gr.themes.Soft()) as demo: gr.Markdown("# 🚀 DeepSeek-OCR-2 智能OCR识别系统") gr.Markdown("上传图片或PDF文件,体验先进的OCR识别技术") with gr.Tabs(): with gr.TabItem("图片识别"): with gr.Row(): with gr.Column(scale=1): image_input = gr.Image( label="上传图片", type="pil", height=400 ) upload_btn = gr.Button("开始识别", variant="primary") with gr.Column(scale=2): text_output = gr.Textbox( label="识别结果", lines=20, max_lines=50, placeholder="识别结果将显示在这里..." ) upload_btn.click( fn=ocr_inference, inputs=[image_input], outputs=[text_output] ) with gr.TabItem("PDF识别"): with gr.Row(): with gr.Column(scale=1): pdf_input = gr.File( label="上传PDF文件", file_types=[".pdf"] ) pdf_btn = gr.Button("处理PDF", variant="primary") with gr.Column(scale=2): pdf_output = gr.Textbox( label="PDF识别结果", lines=20, max_lines=50 ) pdf_btn.click( fn=process_pdf, inputs=[pdf_input], outputs=[pdf_output] ) # 添加使用说明 with gr.Accordion("使用说明", open=False): gr.Markdown(""" ## 使用步骤: 1. **图片识别**:点击"上传图片"选择图片文件,然后点击"开始识别" 2. **PDF识别**:点击"上传PDF文件"选择PDF文档,然后点击"处理PDF" 3. **等待处理**:模型需要一些时间处理,请耐心等待 4. **查看结果**:识别结果会显示在右侧文本框中 ## 支持格式: - 图片:PNG、JPG、JPEG、BMP - 文档:PDF(多页支持) ## 注意事项: - 图片建议清晰度高,文字对比度强 - 大文件处理可能需要较长时间 - 复杂排版可能需要手动调整识别结果 """) # 启动服务 if __name__ == "__main__": demo.launch( server_name="0.0.0.0", server_port=7860, share=False )3.2 启动WebUI服务
保存上面的代码为app.py,然后运行:
python app.py服务启动后,在浏览器中访问http://localhost:7860就能看到WebUI界面了。初次加载模型可能需要一些时间,请耐心等待。
界面主要分为两个部分:
- 图片识别:上传单张图片进行OCR识别
- PDF识别:上传PDF文档,系统会自动将每页转换为图片并进行识别
4. Chrome插件开发与集成
4.1 创建Chrome插件基础结构
为了让OCR功能更方便地用于网页截图,我们来开发一个简单的Chrome插件。首先创建插件的基本文件结构:
deepseek-ocr-extension/ ├── manifest.json # 插件配置文件 ├── popup.html # 弹出窗口HTML ├── popup.js # 弹出窗口JavaScript ├── background.js # 后台脚本 ├── content.js # 内容脚本 └── icons/ # 图标文件夹 ├── icon16.png ├── icon48.png └── icon128.png4.2 配置manifest.json
{ "manifest_version": 3, "name": "DeepSeek OCR助手", "version": "1.0.0", "description": "使用DeepSeek-OCR-2识别网页截图中的文字", "permissions": [ "activeTab", "scripting", "storage" ], "action": { "default_popup": "popup.html", "default_icon": { "16": "icons/icon16.png", "48": "icons/icon48.png", "128": "icons/icon128.png" } }, "background": { "service_worker": "background.js" }, "content_scripts": [ { "matches": ["<all_urls>"], "js": ["content.js"] } ] }4.3 实现截图与OCR功能
popup.html- 弹出窗口界面:
<!DOCTYPE html> <html> <head> <style> body { width: 400px; padding: 20px; font-family: Arial, sans-serif; } .container { display: flex; flex-direction: column; gap: 15px; } button { padding: 10px 20px; background: #4CAF50; color: white; border: none; border-radius: 5px; cursor: pointer; font-size: 14px; } button:hover { background: #45a049; } #status { padding: 10px; background: #f5f5f5; border-radius: 5px; min-height: 50px; word-wrap: break-word; } .loading { display: none; text-align: center; color: #666; } </style> </head> <body> <div class="container"> <h3>DeepSeek OCR助手</h3> <button id="captureVisible">截取可见区域</button> <button id="captureFull">截取整个页面</button> <button id="captureSelection">选择区域截图</button> <div class="loading" id="loading"> 正在识别中,请稍候... </div> <div id="status"> 点击上方按钮开始截图识别 </div> <div class="settings"> <label> <input type="checkbox" id="autoCopy"> 自动复制识别结果 </label> <br> <label> OCR服务器地址: <input type="text" id="serverUrl" value="http://localhost:7860"> </label> </div> </div> <script src="popup.js"></script> </body> </html>popup.js- 弹出窗口逻辑:
document.addEventListener('DOMContentLoaded', function() { const captureVisibleBtn = document.getElementById('captureVisible'); const captureFullBtn = document.getElementById('captureFull'); const captureSelectionBtn = document.getElementById('captureSelection'); const statusDiv = document.getElementById('status'); const loadingDiv = document.getElementById('loading'); const autoCopyCheckbox = document.getElementById('autoCopy'); const serverUrlInput = document.getElementById('serverUrl'); // 从存储中加载设置 chrome.storage.local.get(['autoCopy', 'serverUrl'], function(result) { if (result.autoCopy !== undefined) { autoCopyCheckbox.checked = result.autoCopy; } if (result.serverUrl) { serverUrlInput.value = result.serverUrl; } }); // 保存设置 autoCopyCheckbox.addEventListener('change', function() { chrome.storage.local.set({ autoCopy: this.checked }); }); serverUrlInput.addEventListener('change', function() { chrome.storage.local.set({ serverUrl: this.value }); }); // 截图功能 async function captureScreenshot(captureOptions) { loadingDiv.style.display = 'block'; statusDiv.textContent = '正在截图...'; try { // 获取当前标签页 const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }); // 截图 const dataUrl = await chrome.tabs.captureVisibleTab( tab.windowId, { format: 'png' } ); statusDiv.textContent = '正在发送到OCR服务器...'; // 发送到OCR服务器 const serverUrl = serverUrlInput.value; const response = await sendToOCR(dataUrl, serverUrl); // 显示结果 statusDiv.textContent = response; // 自动复制 if (autoCopyCheckbox.checked) { await navigator.clipboard.writeText(response); statusDiv.textContent += '\n\n✅ 已自动复制到剪贴板'; } } catch (error) { statusDiv.textContent = '错误:' + error.message; } finally { loadingDiv.style.display = 'none'; } } // 发送图片到OCR服务器 async function sendToOCR(dataUrl, serverUrl) { try { // 将dataURL转换为Blob const response = await fetch(dataUrl); const blob = await response.blob(); // 创建FormData const formData = new FormData(); formData.append('image', blob, 'screenshot.png'); // 发送请求 const ocrResponse = await fetch(`${serverUrl}/api/ocr`, { method: 'POST', body: formData }); if (!ocrResponse.ok) { throw new Error(`OCR服务器错误:${ocrResponse.status}`); } const result = await ocrResponse.json(); return result.text || '识别失败'; } catch (error) { throw new Error(`OCR处理失败:${error.message}`); } } // 绑定按钮事件 captureVisibleBtn.addEventListener('click', () => { captureScreenshot({}); }); captureFullBtn.addEventListener('click', async () => { // 对于整个页面截图,需要先滚动到顶部 const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }); await chrome.scripting.executeScript({ target: { tabId: tab.id }, func: () => window.scrollTo(0, 0) }); // 这里简化处理,实际需要分段截图并拼接 captureScreenshot({}); }); captureSelectionBtn.addEventListener('click', () => { statusDiv.textContent = '请先在页面上选择要截图的区域'; // 这里需要实现区域选择功能,为简化示例,我们使用可见区域截图 captureScreenshot({}); }); });4.4 扩展WebUI添加API接口
为了让Chrome插件能与WebUI通信,我们需要在之前的Gradio应用中添加一个API接口:
# 在app.py中添加以下代码 from fastapi import FastAPI, UploadFile, File from fastapi.middleware.cors import CORSMiddleware import uvicorn # 创建FastAPI应用 api_app = FastAPI() # 添加CORS支持 api_app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @api_app.post("/api/ocr") async def api_ocr(image: UploadFile = File(...)): """API接口:接收图片并返回OCR结果""" try: # 读取上传的图片 contents = await image.read() img = Image.open(io.BytesIO(contents)) # 进行OCR识别 result = ocr_inference(img) return {"text": result, "status": "success"} except Exception as e: return {"text": f"识别失败:{str(e)}", "status": "error"} # 修改启动代码,同时启动Gradio和FastAPI import threading def run_gradio(): demo.launch( server_name="0.0.0.0", server_port=7860, share=False, quiet=True ) def run_api(): uvicorn.run(api_app, host="0.0.0.0", port=7861) if __name__ == "__main__": # 启动Gradio服务 gradio_thread = threading.Thread(target=run_gradio) gradio_thread.start() # 启动API服务 api_thread = threading.Thread(target=run_api) api_thread.start() print("服务已启动:") print("WebUI界面:http://localhost:7860") print("API接口:http://localhost:7861") # 等待线程结束 gradio_thread.join() api_thread.join()5. 实际使用演示
5.1 安装与配置Chrome插件
加载插件:
- 打开Chrome浏览器,进入
chrome://extensions/ - 开启右上角的"开发者模式"
- 点击"加载已解压的扩展程序"
- 选择我们创建的
deepseek-ocr-extension文件夹
- 打开Chrome浏览器,进入
配置服务器地址:
- 点击插件图标,打开弹出窗口
- 确保OCR服务器地址正确(默认是
http://localhost:7861) - 如果WebUI运行在其他地址或端口,需要相应修改
5.2 网页截图识别实战
让我们通过几个实际场景来演示插件的使用:
场景一:识别技术文章中的代码截图
- 打开一篇包含代码截图的技术博客
- 点击Chrome插件图标
- 选择"截取可见区域"
- 插件会自动截图并发送到OCR服务器
- 几秒钟后,识别结果就会显示在插件窗口中
- 如果开启了"自动复制",结果还会自动复制到剪贴板
场景二:提取产品文档中的表格数据
- 找到包含数据表格的网页
- 使用"选择区域截图"功能(如果实现了的话)
- 或者调整浏览器窗口,让表格占据主要区域后使用"截取可见区域"
- 获取识别结果后,可以直接粘贴到Excel或文档中
场景三:批量处理多个截图
- 对于需要处理多个截图的情况,可以使用WebUI界面
- 打开
http://localhost:7860 - 在"图片识别"标签页中,可以连续上传多张图片
- 系统会依次处理并显示结果
5.3 识别效果优化技巧
虽然DeepSeek-OCR-2已经很强大,但通过一些技巧可以进一步提升识别效果:
图片预处理:
from PIL import Image, ImageEnhance def preprocess_image(image): """图片预处理:增强对比度和清晰度""" # 转换为灰度图(如果需要) if image.mode != 'L': image = image.convert('L') # 增强对比度 enhancer = ImageEnhance.Contrast(image) image = enhancer.enhance(1.5) # 增强锐度 enhancer = ImageEnhance.Sharpness(image) image = enhancer.enhance(2.0) return image调整识别参数:
# 可以根据不同类型的文档调整参数 def optimize_for_document_type(doc_type): """根据文档类型优化识别参数""" params = { "technical": {"temperature": 0.1, "top_p": 0.9}, "handwritten": {"temperature": 0.2, "top_p": 0.95}, "table": {"temperature": 0.05, "top_p": 0.8} } return params.get(doc_type, {"temperature": 0.1, "top_p": 0.9})后处理优化:
def postprocess_text(text): """对识别结果进行后处理""" # 移除多余的空格和换行 lines = text.strip().split('\n') cleaned_lines = [] for line in lines: line = line.strip() if line: # 跳过空行 # 合并被错误分割的单词 line = ' '.join(line.split()) cleaned_lines.append(line) return '\n'.join(cleaned_lines)
6. 常见问题与解决方案
6.1 安装与部署问题
问题1:模型下载速度慢或失败
解决方案:
# 使用镜像源加速 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple # 或者使用国内镜像下载模型 # 方法一:使用modelscope pip install modelscope from modelscope import snapshot_download model_dir = snapshot_download('deepseek-ai/DeepSeek-OCR-2') # 方法二:手动下载后指定本地路径 model = AutoModelForCausalLM.from_pretrained( "/path/to/local/DeepSeek-OCR-2", device_map="auto" )问题2:内存不足或GPU显存不够
解决方案:
# 使用量化版本减少内存占用 from transformers import BitsAndBytesConfig quantization_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_compute_dtype=torch.float16, bnb_4bit_use_double_quant=True, ) model = AutoModelForCausalLM.from_pretrained( "deepseek-ai/DeepSeek-OCR-2", quantization_config=quantization_config, device_map="auto" ) # 或者使用CPU模式(速度较慢) model = AutoModelForCausalLM.from_pretrained( "deepseek-ai/DeepSeek-OCR-2", device_map="cpu" )6.2 使用过程中的问题
问题3:识别结果不准确
可能原因和解决方案:
- 图片质量差:确保截图清晰,文字对比度足够
- 复杂排版:对于多栏、表格等复杂排版,可以尝试分段识别
- 特殊字体:某些艺术字体或手写体识别难度较大
优化方法:
# 分段识别复杂文档 def segment_and_recognize(image, segment_size=512): """将大图分割成小块分别识别""" width, height = image.size results = [] for y in range(0, height, segment_size): for x in range(0, width, segment_size): # 截取小块 box = (x, y, min(x+segment_size, width), min(y+segment_size, height)) segment = image.crop(box) # 识别该小块 result = ocr_inference(segment) results.append({ "position": (x, y), "text": result }) # 合并结果(这里需要根据实际情况调整合并逻辑) return merge_results(results)问题4:Chrome插件无法连接服务器
检查步骤:
- 确保WebUI和API服务都已启动
- 检查防火墙设置,确保端口7860和7861开放
- 在插件设置中确认服务器地址正确
- 尝试在浏览器中直接访问
http://localhost:7861/api/ocr测试API是否正常
6.3 性能优化建议
提升识别速度:
# 使用批处理提高效率 def batch_ocr(images): """批量处理多张图片""" # 将多张图片合并处理 combined_prompt = "" for img in images: buffered = io.BytesIO() img.save(buffered, format="PNG") img_str = base64.b64encode(buffered.getvalue()).decode() combined_prompt += f"<image>{img_str}</image>\n" combined_prompt += "请依次识别以上图片中的文字内容:" # 批量推理 outputs = llm.generate([combined_prompt], sampling_params) return outputs[0].outputs[0].text # 使用缓存避免重复识别 from functools import lru_cache import hashlib @lru_cache(maxsize=100) def cached_ocr(image_hash): """使用缓存存储已识别的结果""" # 这里需要根据image_hash获取对应的图片和识别结果 pass减少资源占用:
# 动态加载模型,按需使用 class OCRProcessor: def __init__(self): self.model = None self.tokenizer = None def load_model(self): """延迟加载模型,减少启动时的内存占用""" if self.model is None: print("正在加载模型...") self.model = AutoModelForCausalLM.from_pretrained( "deepseek-ai/DeepSeek-OCR-2", device_map="auto" ) self.tokenizer = AutoTokenizer.from_pretrained("deepseek-ai/DeepSeek-OCR-2") def process(self, image): """处理图片""" if self.model is None: self.load_model() # ... 处理逻辑7. 总结
通过本文的介绍,你应该已经掌握了DeepSeek-OCR-2的基本使用方法,以及如何通过Chrome插件和WebUI的联动,实现网页截图的智能识别。这个方案有以下几个显著优势:
主要优势:
- 识别准确率高:DeepSeek-OCR-2采用创新的动态重排技术,在复杂文档识别上表现优异
- 使用方便:Chrome插件让OCR功能触手可及,无需离开浏览器
- 部署简单:基于vllm和gradio的解决方案,几分钟就能搭建完成
- 扩展性强:WebUI界面友好,API接口便于集成到其他系统
实际应用场景:
- 技术学习:快速提取教程中的代码示例
- 资料收集:从网页截图中提取重要信息
- 文档处理:批量识别图片中的文字内容
- 数据整理:从表格截图中提取结构化数据
后续优化方向:
- 插件功能增强:添加区域选择、批量处理、结果编辑等功能
- 识别精度提升:结合版面分析技术,更好地处理复杂排版
- 多语言支持:扩展对更多语言的支持
- 离线模式:开发完全离线的版本,保护隐私数据
DeepSeek-OCR-2的出现,让OCR技术变得更加智能和易用。无论是日常办公还是专业数据处理,这个工具都能显著提升工作效率。希望本文能帮助你快速上手这个强大的工具,在实际工作中发挥它的价值。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
