在开始构建服务之前,我们需要准备运行环境。为了保证服务的可移植性和隔离性,本指南采用 Docker 进行部署。首先确保你的服务器或本地开发环境已经安装了 Docker。
如果你尚未安装 Docker,请根据你的操作系统执行以下命令进行安装。这里以 CentOS 和 Ubuntu 为例:
Ubuntu/Debian 安装命令:
```bash curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun sudo usermod -aG docker $USER newgrp docker ```CentOS/RHEL 安装命令:
```bash sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo yum install -y docker-ce docker-ce-cli containerd.io sudo systemctl start docker ```安装完成后,使用 docker --version 确认版本信息,确保环境正常。
为了保持项目清晰,我们在服务器上创建一个专门的工作目录。执行以下命令:
```bash mkdir -p /data/ocr-service cd /data/ocr-service ```在这个目录下,我们将创建三个核心文件:app.py(主服务代码)、requirements.txt(Python依赖库)、Dockerfile(镜像构建文件)。
我们使用 Python 的 Flask 框架搭建 Web 服务,并集成百度开源的 PaddleOCR 作为识别引擎。PaddleOCR 对中文支持极佳,且提供免费模型,非常适合文书档案场景。
创建并编辑 app.py 文件,写入以下完整代码:
```python import os import base64 import json import cv2 import numpy as np from flask import Flask, request, jsonify from paddleocr import PaddleOCR app = Flask(__name__) 初始化 PaddleOCR use_angle_cls=True 开启方向分类,识别倒置文字 lang='ch' 表示加载中英文模型 print("正在加载 OCR 模型,首次运行需要下载模型文件...") ocr = PaddleOCR(use_angle_cls=True, lang="ch", show_log=False) print("模型加载完成,服务就绪。") @app.route('/ocr', methods=['POST']) def ocr_service(): 检查是否有文件上传 if 'file' not in request.files: return jsonify({"error": "未找到上传文件,请使用 'file' 字段上传图片"}), 400 file = request.files['file'] if file.filename == '': return jsonify({"error": "文件名为空"}), 400 try: 将上传的文件流转换为 OpenCV 可读取的格式 读取文件字节流 file_bytes = np.frombuffer(file.read(), np.uint8) 解码为图片矩阵 img = cv2.imdecode(file_bytes, cv2.IMREAD_COLOR) if img is None: return jsonify({"error": "图片解码失败,请检查文件格式"}), 400 执行 OCR 识别 result = ocr.ocr(img, cls=True) 格式化返回结果 output_data = [] if result and result[0]: for line in result[0]: text_content = line[1][0] confidence = float(line[1][1]) box = line[0] output_data.append({ "text": text_content, "confidence": confidence, "position": box }) return jsonify({ "status": "success", "data": output_data }) except Exception as e: return jsonify({"error": str(e)}), 500 if __name__ == '__main__': 监听 0.0.0.0:5000 app.run(host='0.0.0.0', port=5000) ```代码细节解析:
use_angle_cls=True 非常重要,它能自动识别并旋转倒置或倾斜的文书档案,提高识别率。request.files 获取图片,利用 np.frombuffer 和 cv2.imdecode 直接在内存中处理图片,避免磁盘 I/O 开销,提升并发性能。创建 requirements.txt 文件,定义 Python 环境依赖。为了确保构建顺利,我们需要指定具体的库版本:
```text flask==2.3.3 paddlepaddle==2.5.2 paddleocr==2.7.0.3 opencv-python==4.8.0.76 numpy==1.24.3 ```注意: 这里默认安装 CPU 版本的 PaddlePaddle。如果你的服务器带有 NVIDIA 显卡并安装了 nvidia-docker,可以将 paddlepaddle 替换为 paddlepaddle-gpu 以获得更快的识别速度。

创建 Dockerfile,定义容器运行环境。我们需要安装 OpenCV 所需的系统库,这是构建过程中最容易出错的地方。
```dockerfile 使用 Python 3.9 官方镜像作为基础镜像 FROM python:3.9-slim 设置工作目录 WORKDIR /app 安装系统依赖 libgl1-mesa-glx: OpenCV 依赖的图形库 libglib2.0-0: PaddleOCR 依赖的基础库 RUN apt-get update && apt-get install -y \ libgl1-mesa-glx \ libglib2.0-0 \ && rm -rf /var/lib/apt/lists/ 复制依赖文件到容器内 COPY requirements.txt . 安装 Python 依赖 使用国内清华源加速下载 RUN pip install --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt 复制项目代码到容器内 COPY app.py . 暴露 5000 端口 EXPOSE 5000 启动命令 CMD ["python", "app.py"] ```关键点说明:
slim 版本镜像体积较小,适合生产环境。libgl1-mesa-glx 是必须安装的,否则运行 OpenCV 时会报 libGL.so.1 错误。rm -rf /var/lib/apt/lists/ 用于清理 apt 缓存,减小最终镜像体积。所有文件准备就绪后,我们在 /data/ocr-service 目录下执行构建命令:
```bash docker build -t archive-ocr:v1 . ```构建过程可能需要几分钟,期间会下载 PaddlePaddle 和模型文件。构建成功后,执行以下命令启动容器:
```bash docker run -d -p 5000:5000 --name ocr-server archive-ocr:v1 ```参数解释:
使用 docker logs -f ocr-server 查看日志。当日志中出现 “模型加载完成,服务就绪” 时,说明服务启动成功。
我们可以使用 curl 命令进行简单的接口测试。假设你有一张名为 test.jpg 的图片放在当前目录下:
```bash curl -X POST -F "file=@test.jpg" http://localhost:5000/ocr ```如果一切正常,你将看到返回的 JSON 数据,其中包含了图片中的所有文字内容、置信度以及每个文字在图片中的坐标位置。
返回示例结构如下:
```json { "status": "success", "data": [ { "text": "某某有限公司文书档案", "confidence": 0.998, "position": [[10, 10], [200, 10], [200, 30], [10, 30]] }, { "text": "编号:2023-001", "confidence": 0.995, "position": [[10, 40], [150, 40], [150, 60], [10, 60]] } ] } ```在实操过程中,可能会遇到以下两个主要问题,请参照方案解决:
1. 首次请求响应非常慢
原因:PaddleOCR 在首次执行识别时,会自动从互联网下载推理模型文件到容器内的 ~/.paddleocr/ 目录。
解决:这是正常现象。第二次请求响应速度会显著提升。如果需要预下载模型,可以在 Dockerfile 中添加模型下载脚本,或者在启动脚本中预先执行一次推理。
2. 内存溢出 (OOM)
原因:OCR 是计算密集型任务,处理高分辨率大图时会消耗大量内存。
解决:在代码中添加图片尺寸限制逻辑,使用 cv2.resize 将图片的长边限制在 2000 像素以内,既能保证识别率,又能大幅降低内存占用。