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:
3
utils/__init__.py
Normal file
3
utils/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
"""
|
||||
工具函数包
|
||||
"""
|
||||
75
utils/slide_utils.py
Normal file
75
utils/slide_utils.py
Normal file
@@ -0,0 +1,75 @@
|
||||
"""
|
||||
滑块轨迹生成工具
|
||||
|
||||
生成模拟人类操作的滑块拖拽轨迹。
|
||||
"""
|
||||
|
||||
import math
|
||||
import random
|
||||
|
||||
|
||||
def generate_slide_track(
|
||||
distance: int,
|
||||
duration: float = 1.0,
|
||||
seed: int | None = None,
|
||||
) -> list[dict]:
|
||||
"""
|
||||
生成滑块拖拽轨迹。
|
||||
|
||||
使用贝塞尔曲线 ease-out 加速减速,末尾带微小过冲回退。
|
||||
y 轴 ±1~3px 随机抖动,时间间隔不均匀。
|
||||
|
||||
Args:
|
||||
distance: 滑动距离 (像素)
|
||||
duration: 总时长 (秒)
|
||||
seed: 随机种子
|
||||
|
||||
Returns:
|
||||
[{"x": float, "y": float, "t": float}, ...]
|
||||
"""
|
||||
rng = random.Random(seed)
|
||||
|
||||
if distance <= 0:
|
||||
return [{"x": 0.0, "y": 0.0, "t": 0.0}]
|
||||
|
||||
track = []
|
||||
# 采样点数
|
||||
num_points = rng.randint(30, 60)
|
||||
total_ms = duration * 1000
|
||||
|
||||
# 生成不均匀时间点
|
||||
raw_times = sorted([rng.random() for _ in range(num_points - 2)])
|
||||
times = [0.0] + raw_times + [1.0]
|
||||
|
||||
# 过冲距离
|
||||
overshoot = rng.uniform(2, 6)
|
||||
overshoot_start = 0.85 # 85% 时到达目标 + 过冲
|
||||
|
||||
for t_norm in times:
|
||||
t_ms = round(t_norm * total_ms, 1)
|
||||
|
||||
if t_norm <= overshoot_start:
|
||||
# ease-out: 快速启动,缓慢减速
|
||||
progress = t_norm / overshoot_start
|
||||
eased = 1 - (1 - progress) ** 3 # cubic ease-out
|
||||
x = eased * (distance + overshoot)
|
||||
else:
|
||||
# 过冲回退段
|
||||
retract_progress = (t_norm - overshoot_start) / (1 - overshoot_start)
|
||||
eased_retract = retract_progress ** 2 # ease-in 回退
|
||||
x = (distance + overshoot) - overshoot * eased_retract
|
||||
|
||||
# y 轴随机抖动
|
||||
y_jitter = rng.uniform(-3, 3) if t_norm > 0.05 else 0.0
|
||||
|
||||
track.append({
|
||||
"x": round(x, 1),
|
||||
"y": round(y_jitter, 1),
|
||||
"t": t_ms,
|
||||
})
|
||||
|
||||
# 确保最后一个点精确到达目标
|
||||
track[-1]["x"] = float(distance)
|
||||
track[-1]["y"] = round(rng.uniform(-0.5, 0.5), 1)
|
||||
|
||||
return track
|
||||
Reference in New Issue
Block a user