Complete OpenCV Method 3 implementation with 86.5% handwriting retention

- Implemented comprehensive feature analysis based on size, stroke length, and regularity
- Size-based scoring: height >50px indicates handwriting
- Stroke length ratio: >0.4 indicates handwriting
- Irregularity metrics: low compactness/solidity indicates handwriting
- Successfully tested on sample PDF with 2 signatures (楊智惠, 張志銘)
- Created detailed documentation: CURRENT_STATUS.md and NEW_SESSION_HANDOFF.md
- Stable PaddleOCR 2.7.3 configuration documented (numpy 1.26.4, opencv 4.6.0.66)
- Prepared research plan for PP-OCRv5 upgrade investigation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-27 10:35:46 +08:00
parent 479d4e0019
commit 8f231da3bc
6 changed files with 1718 additions and 0 deletions

91
paddleocr_server_v5.py Normal file
View File

@@ -0,0 +1,91 @@
#!/usr/bin/env python3
"""
PaddleOCR Server v5 (PP-OCRv5)
Flask HTTP server exposing PaddleOCR v3.3.0 functionality
"""
from paddlex import create_model
import base64
import numpy as np
from PIL import Image
from io import BytesIO
from flask import Flask, request, jsonify
import traceback
app = Flask(__name__)
# Initialize PP-OCRv5 model
print("Initializing PP-OCRv5 model...")
model = create_model("PP-OCRv5_server")
print("PP-OCRv5 model loaded successfully!")
@app.route('/health', methods=['GET'])
def health():
"""Health check endpoint."""
return jsonify({
'status': 'ok',
'service': 'paddleocr-server-v5',
'version': '3.3.0',
'model': 'PP-OCRv5_server',
'gpu_enabled': True
})
@app.route('/ocr', methods=['POST'])
def ocr_endpoint():
"""
OCR endpoint using PP-OCRv5.
Accepts: {"image": "base64_encoded_image"}
Returns: {"success": true, "count": N, "results": [...]}
"""
try:
# Parse request
data = request.get_json()
image_base64 = data['image']
# Decode image
image_bytes = base64.b64decode(image_base64)
image = Image.open(BytesIO(image_bytes))
image_np = np.array(image)
# Run OCR with PP-OCRv5
result = model.predict(image_np)
# Format results
formatted_results = []
if result and 'dt_polys' in result[0] and 'rec_text' in result[0]:
dt_polys = result[0]['dt_polys']
rec_texts = result[0]['rec_text']
rec_scores = result[0]['rec_score']
for i in range(len(dt_polys)):
box = dt_polys[i].tolist() # Convert to list
text = rec_texts[i]
confidence = float(rec_scores[i])
formatted_results.append({
'box': box,
'text': text,
'confidence': confidence
})
return jsonify({
'success': True,
'count': len(formatted_results),
'results': formatted_results
})
except Exception as e:
print(f"Error during OCR: {str(e)}")
traceback.print_exc()
return jsonify({
'success': False,
'error': str(e)
}), 500
if __name__ == '__main__':
print("Starting PP-OCRv5 server on port 5555...")
print("Model: PP-OCRv5_server")
print("Version: 3.3.0")
app.run(host='0.0.0.0', port=5555, debug=False)