opex792's picture
Upload app.py
2495559 verified
raw
history blame
5.3 kB
import base64
import logging
import re
import requests
import cv2
import numpy as np
import pytesseract
from flask import Flask, render_template, jsonify
from threading import Lock
import math
app = Flask(__name__)
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
solved_captchas = []
lock = Lock()
CAPTCHA_URL = 'https://checkege.rustest.ru/api/captcha'
HEADERS = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
def deskew(image):
"""
Вычисляет угол наклона и поворачивает изображение, но только если угол адекватен.
"""
gray = cv2.bitwise_not(image)
coords = np.column_stack(np.where(gray > 0))
if len(coords) < 1:
logging.warning("Нет контента для выпрямления, пропуск deskew.")
return image
angle = cv2.minAreaRect(coords)[-1]
if angle < -45:
correction_angle = -(90 + angle)
else:
correction_angle = -angle
# --- КЛЮЧЕВОЕ ИЗМЕНЕНИЕ: ПРОВЕРКА НА АДЕКВАТНОСТЬ ---
# Если вычисленный угол слишком большой, это почти наверняка ошибка.
# Безопаснее пропустить поворот, чем повернуть на 90 градусов.
if abs(correction_angle) > 45:
logging.warning(f"Вычислен неадекватный угол {correction_angle:.2f}. Пропуск коррекции наклона.")
return image
# Пропускаем, если наклон незначителен
if abs(correction_angle) < 1:
logging.info("Угол наклона незначителен, коррекция не требуется.")
return image
logging.info(f"Обнаружен адекватный угол наклона: {correction_angle:.2f} градусов. Применяется коррекция.")
(h, w) = image.shape[:2]
center = (w // 2, h // 2)
M = cv2.getRotationMatrix2D(center, correction_angle, 1.0)
rotated = cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_CONSTANT, borderValue=(255,255,255))
return rotated
def fetch_and_solve_captcha():
try:
logging.info("Получение новой капчи...")
response = requests.get(CAPTCHA_URL, headers=HEADERS)
response.raise_for_status()
data = response.json()
base64_image_data = data.get("Image")
if not base64_image_data:
return None
image_bytes = base64.b64decode(base64_image_data)
nparr = np.frombuffer(image_bytes, np.uint8)
original_image = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
scale_factor = 2
width = int(original_image.shape[1] * scale_factor)
height = int(original_image.shape[0] * scale_factor)
upscaled_image = cv2.resize(original_image, (width, height), interpolation=cv2.INTER_CUBIC)
hsv = cv2.cvtColor(upscaled_image, cv2.COLOR_BGR2HSV)
lower_blue = np.array([90, 50, 50])
upper_blue = np.array([130, 255, 255])
mask = cv2.inRange(hsv, lower_blue, upper_blue)
kernel = np.ones((2, 2), np.uint8)
cleaned_mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel, iterations=2)
inverted_mask = cv2.bitwise_not(cleaned_mask)
deskewed_image = deskew(inverted_mask)
processed_image = deskewed_image
tesseract_config = r'--oem 3 --psm 6 -c tessedit_char_whitelist=0123456789'
text = pytesseract.image_to_string(processed_image, config=tesseract_config)
recognized_text = re.sub(r'\s+', '', text).strip() or "Не распознано"
logging.info(f"Распознано: {recognized_text}")
_, buffer_orig = cv2.imencode('.png', original_image)
original_b64 = base64.b64encode(buffer_orig).decode('utf-8')
_, buffer_proc = cv2.imencode('.png', processed_image)
processed_b64 = base64.b64encode(buffer_proc).decode('utf-8')
return {
"text": recognized_text,
"original_b64": original_b64,
"processed_b64": processed_b64
}
except Exception as e:
logging.error(f"Произошла ошибка при решении капчи: {e}", exc_info=True)
return None
@app.route('/')
def index():
with lock:
return render_template('index.html', captchas=list(solved_captchas))
@app.route('/solve', methods=['POST'])
def solve_new_captcha():
new_captcha = fetch_and_solve_captcha()
if new_captcha:
with lock:
solved_captchas.insert(0, new_captcha)
return jsonify(new_captcha)
return jsonify({"error": "Не удалось решить капчу"}), 500
if __name__ == '__main__':
logging.info("Запуск приложения...")
initial_captcha = fetch_and_solve_captcha()
if initial_captcha:
solved_captchas.append(initial_captcha)
app.run(host='0.0.0.0', port=7860, debug=False)