167 lines
4.3 KiB
Python
167 lines
4.3 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
# -*- coding: utf-8 -*-
|
||
|
|
"""
|
||
|
|
PaddleOCR HTTP API Service
|
||
|
|
基于 PaddlePaddle 官方镜像的 OCR HTTP 服务
|
||
|
|
"""
|
||
|
|
|
||
|
|
from flask import Flask, request, jsonify
|
||
|
|
from paddleocr import PaddleOCR
|
||
|
|
import base64
|
||
|
|
import io
|
||
|
|
from PIL import Image
|
||
|
|
import logging
|
||
|
|
|
||
|
|
# 配置日志
|
||
|
|
logging.basicConfig(level=logging.INFO)
|
||
|
|
logger = logging.getLogger(__name__)
|
||
|
|
|
||
|
|
# 初始化 PaddleOCR
|
||
|
|
ocr = PaddleOCR(
|
||
|
|
use_angle_cls=True,
|
||
|
|
lang='ch',
|
||
|
|
use_gpu=False,
|
||
|
|
show_log=False
|
||
|
|
)
|
||
|
|
|
||
|
|
app = Flask(__name__)
|
||
|
|
|
||
|
|
@app.route('/', methods=['GET'])
|
||
|
|
def index():
|
||
|
|
"""健康检查"""
|
||
|
|
return jsonify({
|
||
|
|
"message": "PaddleOCR Server is running!",
|
||
|
|
"version": "2.7.0",
|
||
|
|
"endpoints": {
|
||
|
|
"/": "GET - 健康检查",
|
||
|
|
"/ocr/scan": "POST - OCR 识别"
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
@app.route('/ocr/scan', methods=['POST'])
|
||
|
|
def ocr_scan():
|
||
|
|
"""OCR 识别接口"""
|
||
|
|
try:
|
||
|
|
# 获取请求数据
|
||
|
|
data = request.get_json()
|
||
|
|
|
||
|
|
if not data or 'image' not in data:
|
||
|
|
return jsonify({
|
||
|
|
"success": False,
|
||
|
|
"error": "Missing image data"
|
||
|
|
}), 400
|
||
|
|
|
||
|
|
# 解码图片
|
||
|
|
image_data = data['image']
|
||
|
|
if isinstance(image_data, str):
|
||
|
|
# Base64 编码
|
||
|
|
if image_data.startswith('data:image'):
|
||
|
|
image_data = image_data.split(',')[1]
|
||
|
|
image_bytes = base64.b64decode(image_data)
|
||
|
|
else:
|
||
|
|
return jsonify({
|
||
|
|
"success": False,
|
||
|
|
"error": "Invalid image format"
|
||
|
|
}), 400
|
||
|
|
|
||
|
|
# 转换为 PIL Image
|
||
|
|
image = Image.open(io.BytesIO(image_bytes))
|
||
|
|
|
||
|
|
# 执行 OCR
|
||
|
|
result = ocr.ocr(image, cls=True)
|
||
|
|
|
||
|
|
# 解析结果
|
||
|
|
if result and result[0]:
|
||
|
|
texts = []
|
||
|
|
for line in result[0]:
|
||
|
|
box = line[0]
|
||
|
|
text_info = line[1]
|
||
|
|
texts.append({
|
||
|
|
"text": text_info[0],
|
||
|
|
"confidence": float(text_info[1]),
|
||
|
|
"box": box
|
||
|
|
})
|
||
|
|
|
||
|
|
all_text = "\n".join([t["text"] for t in texts])
|
||
|
|
|
||
|
|
return jsonify({
|
||
|
|
"success": True,
|
||
|
|
"data": {
|
||
|
|
"texts": texts,
|
||
|
|
"fullText": all_text
|
||
|
|
}
|
||
|
|
})
|
||
|
|
else:
|
||
|
|
return jsonify({
|
||
|
|
"success": False,
|
||
|
|
"error": "No text detected"
|
||
|
|
}), 200
|
||
|
|
|
||
|
|
except Exception as e:
|
||
|
|
logger.error(f"OCR Error: {str(e)}")
|
||
|
|
return jsonify({
|
||
|
|
"success": False,
|
||
|
|
"error": str(e)
|
||
|
|
}), 500
|
||
|
|
|
||
|
|
@app.route('/ocr/text', methods=['POST'])
|
||
|
|
def ocr_text():
|
||
|
|
"""简化的 OCR 接口,只返回文本"""
|
||
|
|
try:
|
||
|
|
data = request.get_json()
|
||
|
|
|
||
|
|
if not data or 'image' not in data:
|
||
|
|
return jsonify({
|
||
|
|
"success": False,
|
||
|
|
"error": "Missing image data"
|
||
|
|
}), 400
|
||
|
|
|
||
|
|
# 解码图片
|
||
|
|
image_data = data['image']
|
||
|
|
if isinstance(image_data, str):
|
||
|
|
if image_data.startswith('data:image'):
|
||
|
|
image_data = image_data.split(',')[1]
|
||
|
|
image_bytes = base64.b64decode(image_data)
|
||
|
|
else:
|
||
|
|
return jsonify({
|
||
|
|
"success": False,
|
||
|
|
"error": "Invalid image format"
|
||
|
|
}), 400
|
||
|
|
|
||
|
|
image = Image.open(io.BytesIO(image_bytes))
|
||
|
|
|
||
|
|
# 执行 OCR
|
||
|
|
result = ocr.ocr(image, cls=True)
|
||
|
|
|
||
|
|
# 提取文本
|
||
|
|
if result and result[0]:
|
||
|
|
texts = [line[1][0] for line in result[0]]
|
||
|
|
all_text = "\n".join(texts)
|
||
|
|
|
||
|
|
return jsonify({
|
||
|
|
"success": True,
|
||
|
|
"data": {
|
||
|
|
"text": all_text,
|
||
|
|
"lines": texts
|
||
|
|
}
|
||
|
|
})
|
||
|
|
else:
|
||
|
|
return jsonify({
|
||
|
|
"success": True,
|
||
|
|
"data": {
|
||
|
|
"text": "",
|
||
|
|
"lines": []
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
except Exception as e:
|
||
|
|
logger.error(f"OCR Error: {str(e)}")
|
||
|
|
return jsonify({
|
||
|
|
"success": False,
|
||
|
|
"error": str(e)
|
||
|
|
}), 500
|
||
|
|
|
||
|
|
if __name__ == '__main__':
|
||
|
|
logger.info("Starting PaddleOCR API server on port 8866...")
|
||
|
|
app.run(host='0.0.0.0', port=8866, debug=False)
|