EasyOCR
# Интеграция VNTranslator OCR с движком EasyOCR
# Версия: 1.0
# Автор: Fazx - GarudaMods | https://www.patreon.com/vntranslator
"""
# ==================================================================
# EasyOCR: https://github.com/JaidedAI/EasyOCR
# Требуется: python 3.10+ и PyTorch
# Установить: pip install easyocr
# ==================================================================
# Запустите этот скрипт: python vntocr_easyocr.py
# В VNTranslator используйте Custom Engine - HTTP POST с конфигурацией:
# -- URL: http://127.0.0.1:5353
# -- Тип содержимого: application/json
# -- Заголовки: {}
# -- Тело: {"image":"$IMAGE_BASE64", "langs": ["ja"]}
# -- Тип ответа: JSON
# -- Путь к ответу: fullText
# ==================================================================
# Языки (двухбуквенные ISO) https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes
# -- Японский = ja
# -- Английский = en
# ==================================================================
"""
from flask import Flask, request, jsonify
from PIL import Image
from io import BytesIO
import base64
import re
import json
import numpy as np
import easyocr
APP_HOST = "localhost"
APP_PORT = 5353
APP_DEBUG = True
def parse_ocr_result(easyocr_result):
full_text = ""
lines = []
for entry in easyocr_result:
polygon = entry[0]
text = entry[1]
confidence = entry[2]
x_min = int(min(point[0] for point in polygon))
y_min = int(min(point[1] for point in polygon))
x_max = int(max(point[0] for point in polygon))
y_max = int(max(point[1] for point in polygon))
w = x_max - x_min
h = y_max - y_min
x = x_min
y = y_min
lines.append({
"text": text,
"w": int(w),
"h": int(h),
"x": int(x),
"y": int(y),
"confidence": float(confidence)
})
full_text += text + " "
full_text = full_text.strip()
return {
"fullText": full_text,
"lines": lines
}
def base64_to_numpy(base64_string):
if not base64_string:
raise ValueError("Строка Base64 пустая или отсутствует")
if "," in base64_string:
base64_string = base64_string.split(",")[1]
try:
image_decode = base64.b64decode(base64_string)
print("Декодирование Base64 успешно")
# открыть изображение с помощью PIL
image = Image.open(BytesIO(image_decode))
print(f"Формат изображения: {image.format}, размер: {image.size}")
# преобразовать изображение PIL в массив NumPy
image_np = np.array(image)
print(f"Преобразовано изображение в массив NumPy с формой: {image_np.shape}")
return image_np
except Exception as e:
raise ValueError(f"Не удалось декодировать изображение: {e}")
############################################################
app = Flask(__name__)
default_langs = ["ja"]
reader = easyocr.Reader(default_langs)
@app.route("/", methods=["POST"])
def ocr_endpoint():
global default_langs, reader
try:
print("\n\n=== OCR Request ===")
print(f"Метод: {request.method}")
print(f"Заголовки: {dict(request.headers)}")
if not request.is_json:
print("Запрос не в формате JSON")
return jsonify({"error": "Запрос должен быть в формате JSON"}), 400
data = request.get_json()
# логировать полезную нагрузку
print(f"Ключи JSON запроса: {list(data.keys())}")
# проверить изображение
if "image" not in data:
print("Нет данных изображения")
return jsonify({"error": "Нет данных изображения"}), 400
# декодировать изображение base64
try:
image = base64_to_numpy(data["image"])
except Exception as e:
print(f"Ошибка декодирования изображения: {e}")
return jsonify({"error": f"Ошибка декодирования изображения: {str(e)}"}), 400
# проверить языки
langs = data.get("langs", ["ja"])
try:
if langs != default_langs:
default_langs = langs
reader = easyocr.Reader(default_langs)
except Exception as e:
print(f"Ошибка загрузки модели: {e}")
return jsonify({"error": f"Ошибка загрузки модели: {str(e)}"}), 400
print(f"langs: {langs}")
# проверить отрисовку рамок
draw_bounding_box = data.get("draw_bounding_box", False)
print(f"draw_bounding_box: {draw_bounding_box}")
# запустить ocr
# https://github.com/JaidedAI/EasyOCR?tab=readme-ov-file#usage
result = reader.readtext(image)
print(f"OCR успешно завершен: {result}")
# разобрать результат
parsed_result = parse_ocr_result(result)
parsed_result["draw_bounding_box"] = draw_bounding_box
json_result = json.dumps(parsed_result, indent=4, ensure_ascii=False)
return json_result
except Exception as e:
print(f"Ошибка запроса: {e}")
return jsonify({"error": str(e)}), 500
if __name__ == "__main__":
print(f"=== Запуск OCR сервера {APP_HOST} на порту {APP_PORT} ===")
app.run(debug=APP_DEBUG, host=APP_HOST, port=APP_PORT)