Spaces:
Running
Running
File size: 5,299 Bytes
cefe58f 2495559 cefe58f 2495559 5239c02 2495559 5239c02 2495559 5985dd0 2495559 5239c02 2495559 f318822 2495559 5239c02 2495559 5985dd0 2495559 f318822 2495559 f318822 2495559 5239c02 2495559 5239c02 cefe58f 2495559 cefe58f 2495559 5239c02 2d8ec0b 5a423af 5239c02 2495559 5a423af 2495559 5a423af 2495559 cefe58f 2495559 cefe58f 5239c02 cefe58f 2495559 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
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)
|