Add slide and rotate interactive captcha solvers
New solver subsystem with independent models: - GapDetectorCNN (1x128x256 grayscale → sigmoid) for slide gap detection - RotationRegressor (3x128x128 RGB → sin/cos via tanh) for rotation angle prediction - SlideSolver with 3-tier strategy: template match → edge detect → CNN fallback - RotateSolver with ONNX sin/cos → atan2 inference - Generators, training scripts, CLI commands, and slide track utility Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -18,11 +18,14 @@ from config import (
|
||||
THREED_CHARS,
|
||||
NUM_CAPTCHA_TYPES,
|
||||
REGRESSION_RANGE,
|
||||
SOLVER_CONFIG,
|
||||
)
|
||||
from models.classifier import CaptchaClassifier
|
||||
from models.lite_crnn import LiteCRNN
|
||||
from models.threed_cnn import ThreeDCNN
|
||||
from models.regression_cnn import RegressionCNN
|
||||
from models.gap_detector import GapDetectorCNN
|
||||
from models.rotation_regressor import RotationRegressor
|
||||
|
||||
|
||||
def export_model(
|
||||
@@ -52,7 +55,7 @@ def export_model(
|
||||
dummy = torch.randn(1, *input_shape)
|
||||
|
||||
# 分类器和识别器的 dynamic_axes 不同
|
||||
if model_name == "classifier" or model_name in ("threed_rotate", "threed_slider"):
|
||||
if model_name == "classifier" or model_name in ("threed_rotate", "threed_slider", "gap_detector", "rotation_regressor"):
|
||||
dynamic_axes = {"input": {0: "batch"}, "output": {0: "batch"}}
|
||||
else:
|
||||
# CTC 模型: output shape = (T, B, C)
|
||||
@@ -110,6 +113,14 @@ def _load_and_export(model_name: str):
|
||||
h, w = IMAGE_SIZE["3d_slider"]
|
||||
model = RegressionCNN(img_h=h, img_w=w)
|
||||
input_shape = (1, h, w)
|
||||
elif model_name == "gap_detector":
|
||||
h, w = SOLVER_CONFIG["slide"]["cnn_input_size"]
|
||||
model = GapDetectorCNN(img_h=h, img_w=w)
|
||||
input_shape = (1, h, w)
|
||||
elif model_name == "rotation_regressor":
|
||||
h, w = SOLVER_CONFIG["rotate"]["input_size"]
|
||||
model = RotationRegressor(img_h=h, img_w=w)
|
||||
input_shape = (3, h, w)
|
||||
else:
|
||||
print(f"[错误] 未知模型: {model_name}")
|
||||
return
|
||||
@@ -119,11 +130,15 @@ def _load_and_export(model_name: str):
|
||||
|
||||
|
||||
def export_all():
|
||||
"""依次导出 classifier, normal, math, threed_text, threed_rotate, threed_slider 六个模型。"""
|
||||
"""依次导出全部模型 (含 solver 模型)。"""
|
||||
print("=" * 50)
|
||||
print("导出全部 ONNX 模型")
|
||||
print("=" * 50)
|
||||
for name in ["classifier", "normal", "math", "threed_text", "threed_rotate", "threed_slider"]:
|
||||
for name in [
|
||||
"classifier", "normal", "math", "threed_text",
|
||||
"threed_rotate", "threed_slider",
|
||||
"gap_detector", "rotation_regressor",
|
||||
]:
|
||||
_load_and_export(name)
|
||||
print("\n全部导出完成。")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user