Files
CaptchBreaker/config.py

335 lines
12 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
全局配置 - 验证码识别多模型系统 (CaptchaBreaker)
定义字符集、图片尺寸、路径、训练超参等所有全局常量。
"""
import os
from pathlib import Path
# ============================================================
# 项目根目录
# ============================================================
PROJECT_ROOT = Path(__file__).resolve().parent
# ============================================================
# 数据目录
# ============================================================
DATA_DIR = PROJECT_ROOT / "data"
SYNTHETIC_DIR = DATA_DIR / "synthetic"
REAL_DIR = DATA_DIR / "real"
CLASSIFIER_DIR = DATA_DIR / "classifier"
SERVER_TASKS_DIR = DATA_DIR / "server_tasks"
# 合成数据子目录
SYNTHETIC_NORMAL_DIR = SYNTHETIC_DIR / "normal"
SYNTHETIC_MATH_DIR = SYNTHETIC_DIR / "math"
SYNTHETIC_3D_TEXT_DIR = SYNTHETIC_DIR / "3d_text"
SYNTHETIC_3D_ROTATE_DIR = SYNTHETIC_DIR / "3d_rotate"
SYNTHETIC_3D_SLIDER_DIR = SYNTHETIC_DIR / "3d_slider"
# 真实数据子目录
REAL_NORMAL_DIR = REAL_DIR / "normal"
REAL_MATH_DIR = REAL_DIR / "math"
REAL_3D_TEXT_DIR = REAL_DIR / "3d_text"
REAL_3D_ROTATE_DIR = REAL_DIR / "3d_rotate"
REAL_3D_SLIDER_DIR = REAL_DIR / "3d_slider"
REAL_FUN_CAPTCHA_DIR = REAL_DIR / "funcaptcha"
REAL_FUN_CAPTCHA_ROLLBALL_DIR = REAL_FUN_CAPTCHA_DIR / "4_3d_rollball_animals"
# Solver 数据目录
SOLVER_DATA_DIR = DATA_DIR / "solver"
SLIDE_DATA_DIR = SOLVER_DATA_DIR / "slide"
ROTATE_SOLVER_DATA_DIR = SOLVER_DATA_DIR / "rotate"
# ============================================================
# 模型输出目录
# ============================================================
CHECKPOINTS_DIR = PROJECT_ROOT / "checkpoints"
ONNX_DIR = PROJECT_ROOT / "onnx_models"
# 确保关键目录存在
for _dir in [
SYNTHETIC_NORMAL_DIR, SYNTHETIC_MATH_DIR,
SYNTHETIC_3D_TEXT_DIR, SYNTHETIC_3D_ROTATE_DIR, SYNTHETIC_3D_SLIDER_DIR,
REAL_NORMAL_DIR, REAL_MATH_DIR,
REAL_3D_TEXT_DIR, REAL_3D_ROTATE_DIR, REAL_3D_SLIDER_DIR,
REAL_FUN_CAPTCHA_DIR, REAL_FUN_CAPTCHA_ROLLBALL_DIR,
CLASSIFIER_DIR, CHECKPOINTS_DIR, ONNX_DIR,
SLIDE_DATA_DIR, ROTATE_SOLVER_DATA_DIR,
SERVER_TASKS_DIR,
]:
_dir.mkdir(parents=True, exist_ok=True)
# ============================================================
# 字符集定义
# ============================================================
# 普通字符验证码: 按当前本地配置保留易混淆字符,覆盖完整数字 + 大写字母
NORMAL_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
# 算式验证码: 数字 + 运算符
MATH_CHARS = "0123456789+-×÷=?"
# 3D 验证码: 继续使用去掉易混淆字符的精简字符集
THREED_CHARS = "23456789ABCDEFGHJKMNPQRSTUVWXYZ"
# 验证码类型列表 (调度分类器输出)
CAPTCHA_TYPES = ["normal", "math", "3d_text", "3d_rotate", "3d_slider"]
NUM_CAPTCHA_TYPES = len(CAPTCHA_TYPES)
# ============================================================
# 图片尺寸配置 (H, W)
# ============================================================
IMAGE_SIZE = {
"classifier": (64, 128), # 调度分类器输入
"normal": (40, 120), # 普通字符识别
"math": (40, 160), # 算式识别 (更宽)
"3d_text": (60, 160), # 3D 立体文字识别
"3d_rotate": (80, 80), # 3D 旋转角度回归 (正方形)
"3d_slider": (80, 240), # 3D 滑块偏移回归
"funcaptcha_rollball_animals": (48, 48), # FunCaptcha 专项 Siamese 输入
}
# ============================================================
# 验证码生成参数
# ============================================================
GENERATE_CONFIG = {
"normal": {
"char_count_range": (4, 5), # 字符数量: 4-5 个
"bg_color_range": (230, 255), # 浅色背景 RGB 各通道
"rotation_range": (-15, 15), # 字符旋转角度
"noise_line_range": (2, 5), # 干扰线数量
"noise_point_num": 100, # 噪点数量
"blur_radius": 0.8, # 高斯模糊半径
"image_size": (120, 40), # 生成图片尺寸 (W, H)
},
"math": {
"operand_range": (1, 30), # 操作数范围
"operators": ["+", "-", "×", "÷"], # 支持的运算符 (除法只生成能整除的)
"image_size": (160, 40), # 生成图片尺寸 (W, H)
"bg_color_range": (230, 255),
"rotation_range": (-10, 10),
"noise_line_range": (2, 4),
},
"3d_text": {
"char_count_range": (4, 5),
"image_size": (160, 60), # 生成图片尺寸 (W, H)
"shadow_offset": (3, 3), # 阴影偏移
"perspective_intensity": 0.3, # 透视变换强度
"rotation_range": (-20, 20), # 字符旋转角度
},
"3d_rotate": {
"image_size": (80, 80), # 生成图片尺寸 (W, H)
"disc_radius": 35, # 圆盘半径
"marker_size": 8, # 方向标记大小
"bg_color_range": (200, 240), # 背景色范围
},
"3d_slider": {
"image_size": (240, 80), # 生成图片尺寸 (W, H)
"puzzle_size": (40, 40), # 拼图块大小 (W, H)
"gap_x_range": (50, 200), # 缺口 x 坐标范围
"piece_left_margin": 5, # 拼图块左侧留白
"bg_noise_intensity": 30, # 背景纹理噪声强度
},
}
# ============================================================
# 训练配置
# ============================================================
TRAIN_CONFIG = {
"classifier": {
"epochs": 30,
"batch_size": 128,
"lr": 1e-3,
"scheduler": "cosine",
"synthetic_samples": 50000, # 每类 10000 × 5 类
"val_split": 0.1, # 验证集比例
},
"normal": {
"epochs": 50,
"batch_size": 128,
"lr": 1e-3,
"scheduler": "cosine",
"synthetic_samples": 60000,
"loss": "CTCLoss",
"val_split": 0.1,
},
"math": {
"epochs": 50,
"batch_size": 128,
"lr": 1e-3,
"scheduler": "cosine",
"synthetic_samples": 60000,
"loss": "CTCLoss",
"val_split": 0.1,
},
"3d_text": {
"epochs": 80,
"batch_size": 64,
"lr": 5e-4,
"scheduler": "cosine",
"synthetic_samples": 80000,
"loss": "CTCLoss",
"val_split": 0.1,
},
"3d_rotate": {
"epochs": 60,
"batch_size": 128,
"lr": 1e-3,
"scheduler": "cosine",
"synthetic_samples": 60000,
"loss": "SmoothL1",
"val_split": 0.1,
},
"3d_slider": {
"epochs": 60,
"batch_size": 128,
"lr": 1e-3,
"scheduler": "cosine",
"synthetic_samples": 60000,
"loss": "SmoothL1",
"val_split": 0.1,
},
"funcaptcha_rollball_animals": {
"epochs": 30,
"batch_size": 64,
"lr": 1e-3,
"scheduler": "cosine",
"loss": "BCEWithLogits",
"val_split": 0.1,
},
}
# ============================================================
# 数据增强参数 (训练时使用)
# ============================================================
AUGMENT_CONFIG = {
"degrees": 8, # RandomAffine 旋转范围
"translate": (0.05, 0.05), # 平移范围
"scale": (0.95, 1.05), # 缩放范围
"brightness": 0.3, # ColorJitter 亮度
"contrast": 0.3, # ColorJitter 对比度
"blur_kernel": 3, # GaussianBlur 核大小
"blur_sigma": (0.1, 0.5), # GaussianBlur sigma
"erasing_prob": 0.15, # RandomErasing 概率
"erasing_scale": (0.01, 0.05), # RandomErasing 面积比
}
# ============================================================
# ONNX 导出配置
# ============================================================
ONNX_CONFIG = {
"opset_version": 18,
"dynamic_batch": True, # 支持动态 batch size
}
# ============================================================
# 回归模型标签范围
# ============================================================
REGRESSION_RANGE = {
"3d_rotate": (0, 360), # 旋转角度 0-359°
"3d_slider": (10, 200), # 滑块 x 偏移 (像素)
}
# ============================================================
# 推理配置
# ============================================================
INFERENCE_CONFIG = {
"default_models_dir": str(ONNX_DIR),
"normalize_mean": 0.5,
"normalize_std": 0.5,
}
# ============================================================
# FunCaptcha 专项任务配置
# ============================================================
FUN_CAPTCHA_TASKS = {
"4_3d_rollball_animals": {
"artifact_name": "funcaptcha_rollball_animals",
"checkpoint_name": "funcaptcha_rollball_animals",
"data_dir": REAL_FUN_CAPTCHA_ROLLBALL_DIR,
"input_size": IMAGE_SIZE["funcaptcha_rollball_animals"], # (H, W)
"tile_size": (200, 200), # (W, H)
"reference_box": (0, 200, 200, 400), # (x1, y1, x2, y2)
"num_candidates": 4,
"answer_index_base": 0,
"channels": 3,
"external_model_env": "FUNCAPTCHA_ROLLBALL_MODEL_PATH",
"fallback_model_paths": [
str(PROJECT_ROOT.parent / "funcaptcha-server" / "model" / "4_3d_rollball_animals.onnx"),
],
},
}
# ============================================================
# 随机种子 (保证数据生成可复现)
# ============================================================
RANDOM_SEED = 42
# ============================================================
# 设备配置 (优先 GPU回退 CPU)
# 延迟导入 torch避免仅使用生成器时必须安装 torch
# ============================================================
def get_device():
"""返回可用的 torch 设备,优先 GPU。"""
import torch
return torch.device("cuda" if torch.cuda.is_available() else "cpu")
# ============================================================
# 服务配置 (可选 HTTP 服务)
# ============================================================
SERVER_CONFIG = {
"host": "0.0.0.0",
"port": 8080,
"task_ttl_seconds": 600,
"task_workers": 2,
"tasks_dir": str(SERVER_TASKS_DIR),
"callback_timeout_seconds": 10,
"callback_max_retries": 2,
"callback_retry_delay_seconds": 1.0,
"callback_retry_backoff": 2.0,
"callback_signing_secret": os.getenv("CALLBACK_SIGNING_SECRET")
or os.getenv("CAPTCHA_CALLBACK_SIGNING_SECRET"),
"balance": 999999.0,
"task_cost": 0.0,
"client_key": os.getenv("CLIENT_KEY") or os.getenv("CAPTCHA_CLIENT_KEY"),
}
# ============================================================
# Solver 配置 (交互式验证码求解)
# ============================================================
SOLVER_CONFIG = {
"slide": {
"canny_low": 50,
"canny_high": 150,
"cnn_input_size": (128, 256), # H, W
},
"rotate": {
"input_size": (128, 128), # H, W
"channels": 3, # RGB
},
}
SOLVER_TRAIN_CONFIG = {
"slide_cnn": {
"epochs": 50,
"batch_size": 64,
"lr": 1e-3,
"synthetic_samples": 30000,
"val_split": 0.1,
},
"rotate": {
"epochs": 80,
"batch_size": 64,
"lr": 5e-4,
"synthetic_samples": 50000,
"val_split": 0.1,
},
}
SOLVER_REGRESSION_RANGE = {
# 在 solver 输入宽度空间内预测缺口中心 x 坐标,再通过 sigmoid 归一化到 [0, 1]
"slide": (0, SOLVER_CONFIG["slide"]["cnn_input_size"][1]),
"rotate": (0, 360), # 角度
}