Spaces:
Sleeping
Sleeping
Upload app.py
Browse files
app.py
CHANGED
|
@@ -20,6 +20,10 @@ HEADERS = {
|
|
| 20 |
}
|
| 21 |
|
| 22 |
def fetch_and_solve_captcha():
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
try:
|
| 24 |
logging.info("Получение новой капчи...")
|
| 25 |
response = requests.get(CAPTCHA_URL, headers=HEADERS)
|
|
@@ -35,31 +39,33 @@ def fetch_and_solve_captcha():
|
|
| 35 |
nparr = np.frombuffer(image_bytes, np.uint8)
|
| 36 |
original_image = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
|
| 37 |
|
| 38 |
-
# ---
|
| 39 |
-
hsv = cv2.cvtColor(original_image, cv2.COLOR_BGR2HSV)
|
| 40 |
-
lower_blue = np.array([90, 50, 50])
|
| 41 |
-
upper_blue = np.array([130, 255, 255])
|
| 42 |
-
mask = cv2.inRange(hsv, lower_blue, upper_blue)
|
| 43 |
|
| 44 |
-
#
|
| 45 |
-
|
| 46 |
-
# Размер 2x2 хорошо подходит для удаления мелких артефактов.
|
| 47 |
-
kernel = np.ones((2, 2), np.uint8)
|
| 48 |
-
|
| 49 |
-
# Применяем операцию "Открытие" (Opening).
|
| 50 |
-
# Это эрозия, за которой следует расширение. Она удаляет мелкий шум (ошмётки).
|
| 51 |
-
logging.info("Применение морфологического открытия для удаления шума...")
|
| 52 |
-
cleaned_mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel, iterations=1)
|
| 53 |
-
|
| 54 |
-
# --- Этап 3: Инверсия и распознавание ---
|
| 55 |
-
# Инвертируем очищенную маску для Tesseract (черный текст на белом фоне)
|
| 56 |
-
processed_image = cv2.bitwise_not(cleaned_mask)
|
| 57 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
tesseract_config = r'--oem 3 --psm 7 -c tessedit_char_whitelist=ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
|
| 59 |
text = pytesseract.image_to_string(processed_image, config=tesseract_config)
|
| 60 |
recognized_text = re.sub(r'\s+', '', text).strip() or "Не распознано"
|
|
|
|
| 61 |
logging.info(f"Распознано: {recognized_text}")
|
| 62 |
|
|
|
|
| 63 |
_, buffer_orig = cv2.imencode('.png', original_image)
|
| 64 |
original_b64 = base64.b64encode(buffer_orig).decode('utf-8')
|
| 65 |
|
|
@@ -98,3 +104,4 @@ if __name__ == '__main__':
|
|
| 98 |
app.run(host='0.0.0.0', port=7860, debug=False)
|
| 99 |
|
| 100 |
|
|
|
|
|
|
| 20 |
}
|
| 21 |
|
| 22 |
def fetch_and_solve_captcha():
|
| 23 |
+
"""
|
| 24 |
+
Получает, обрабатывает и распознает капчу, используя надежный метод
|
| 25 |
+
адаптивного порогового преобразования.
|
| 26 |
+
"""
|
| 27 |
try:
|
| 28 |
logging.info("Получение новой капчи...")
|
| 29 |
response = requests.get(CAPTCHA_URL, headers=HEADERS)
|
|
|
|
| 39 |
nparr = np.frombuffer(image_bytes, np.uint8)
|
| 40 |
original_image = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
|
| 41 |
|
| 42 |
+
# --- НОВЫЙ, БОЛЕЕ НАДЕЖНЫЙ ПАЙПЛАЙН ОБРАБОТКИ ---
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
|
| 44 |
+
# 1. Конвертируем в оттенки серого. Это делает метод независимым от цвета.
|
| 45 |
+
gray_image = cv2.cvtColor(original_image, cv2.COLOR_BGR2GRAY)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
|
| 47 |
+
# 2. Применяем адаптивное пороговое преобразование.
|
| 48 |
+
# Это лучший способ отделить текст от фона с меняющейся яркостью (сетки).
|
| 49 |
+
# cv2.ADAPTIVE_THRESH_GAUSSIAN_C: использует взвешенное среднее по Гауссу для определения порога.
|
| 50 |
+
# cv2.THRESH_BINARY: основной метод порогового преобразования.
|
| 51 |
+
# 15: Размер окрестности для вычисления порога.
|
| 52 |
+
# 4: Константа, вычитаемая из среднего значения.
|
| 53 |
+
processed_image = cv2.adaptiveThreshold(
|
| 54 |
+
gray_image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
|
| 55 |
+
cv2.THRESH_BINARY, 15, 4)
|
| 56 |
+
|
| 57 |
+
# 3. Инвертируем изображение (Tesseract лучше работает с черным текстом на белом фоне)
|
| 58 |
+
processed_image = cv2.bitwise_not(processed_image)
|
| 59 |
+
|
| 60 |
+
# 4. Распознавание
|
| 61 |
+
# Белый список содержит и буквы, и цифры, т.к. оба варианта встречаются.
|
| 62 |
tesseract_config = r'--oem 3 --psm 7 -c tessedit_char_whitelist=ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
|
| 63 |
text = pytesseract.image_to_string(processed_image, config=tesseract_config)
|
| 64 |
recognized_text = re.sub(r'\s+', '', text).strip() or "Не распознано"
|
| 65 |
+
|
| 66 |
logging.info(f"Распознано: {recognized_text}")
|
| 67 |
|
| 68 |
+
# Кодируем изображения обратно в base64 для отображения в HTML
|
| 69 |
_, buffer_orig = cv2.imencode('.png', original_image)
|
| 70 |
original_b64 = base64.b64encode(buffer_orig).decode('utf-8')
|
| 71 |
|
|
|
|
| 104 |
app.run(host='0.0.0.0', port=7860, debug=False)
|
| 105 |
|
| 106 |
|
| 107 |
+
|