🤖 nantibot-captcha
⚡ Lightweight CRNN + BiLSTM + CTC solver for 5-digit image captchas (grayscale, overlapping wavy digits).
⚡ Solver leve CRNN + BiLSTM + CTC para captchas de imagem de 5 dígitos (tons de cinza, dígitos ondulados sobrepostos).
🧠 Model details / Detalhes do modelo
EN: CNN 1→16→32→64 + BiLSTM (hidden=64, 1 layer, bidirectional) + linear → 11 classes (CTC blank = 0).
Input: grayscale, resized to 32×128, normalized to [-1, 1] (mean=0.5, std=0.5).
Labels: digit indices shifted by +1 (blank reserved at 0). Greedy CTC decoding.
Trainable params: 189,803. Checkpoint: captcha_model.pth (plain PyTorch state_dict, ~752 KB).
Inference code: model.py (architecture + transforms + decode), predict_captcha.py (CLI + CaptchaPredictor class).
PT: CNN 1→16→32→64 + BiLSTM (hidden=64, 1 camada, bidirecional) + linear → 11 classes (branco CTC = 0).
Entrada: tons de cinza, redimensionada para 32×128, normalizada para [-1, 1] (mean=0.5, std=0.5).
Rótulos: índices dos dígitos deslocados em +1 (branco reservado no 0). Decodificação CTC gulosa.
Parâmetros treináveis: 189.803. Checkpoint: captcha_model.pth (state_dict PyTorch puro, ~752 KB).
Código de inferência: model.py (arquitetura + transforms + decode), predict_captcha.py (CLI + classe CaptchaPredictor).
🗂️ Training data / Dados de treino
EN: 715 labeled 5-digit captcha images (from 721 manual labels, 6 skipped as unreadable).
Split (seed 42): 607 train / 108 validation (test_size=0.15).
Source images are 128×128 RGBA, converted to grayscale and resized at load time.
Training: CTCLoss, Adam (lr=1e-3, weight-decay=1e-4), batch 32, mild affine augmentation
(translate ±3%, scale 0.97–1.03), early stopping on validation sequence accuracy (patience 30).
The training script is intentionally not shipped here — inference only.
PT: 715 imagens rotuladas de captcha de 5 dígitos (de 721 rótulos manuais, 6 descartados como ilegíveis).
Divisão (seed 42): 607 treino / 108 validação (test_size=0.15).
Imagens originais 128×128 RGBA, convertidas para cinza e redimensionadas no carregamento.
Treino: CTCLoss, Adam (lr=1e-3, weight-decay=1e-4), batch 32, aumento afim leve
(translate ±3%, scale 0.97–1.03), parada antecipada pela acurácia de sequência na validação (paciência 30).
O script de treino não acompanha este pacote de propósito — somente inferência.
📈 Metrics / Métricas
EN: 🎯 Validation exact-match sequence accuracy: 84.3% (91/108, best checkpoint). Train accuracy at stop: ~98–99% (expected overfit on 607 samples). No test set beyond the validation split; the tables below are the honest held-out evidence.
PT: 🎯 Acurácia de sequência (acerto exato) na validação: 84,3% (91/108, melhor checkpoint). Acurácia de treino ao parar: ~98–99% (overfit esperado em 607 amostras). Sem conjunto de teste além da divisão de validação; as tabelas abaixo são a evidência honesta em dados retidos.
🧪 Real inference experiments / Experimentos reais de inferência
EN: 🔍 Decoding is greedy CTC, exact string match. Validation slice (seed-42 split, first 12):
PT: 🔍 Decodificação CTC gulosa, comparação exata de string. Fatia da validação (divisão seed-42, 12 primeiras):
| file / arquivo | true / real | pred | match |
|---|---|---|---|
| captcha_0121_Frost0n3nek.png | 63557 | 63557 | ✅ yes / sim |
| captcha_mr8gg49o_auto_56qutc.png | 38961 | 38961 | ✅ yes / sim |
| captcha_0040_Sunny9zmnn4.png | 45366 | 45366 | ✅ yes / sim |
| captcha_0300_Sunnyc8a41r.png | 48510 | 48510 | ✅ yes / sim |
| captcha_mr8h4t5f_auto_dykarj.png | 40541 | 40541 | ✅ yes / sim |
| captcha_mr8dx7yb_auto_nx4ayp.png | 63055 | 63055 | ✅ yes / sim |
| captcha_0068_Minerox9cb8.png | 56141 | 56141 | ✅ yes / sim |
| captcha_mr8fr3rx_auto_f6jp3p.png | 64783 | 64783 | ✅ yes / sim |
| captcha_0080_Lunaju0y74.png | 43783 | 43783 | ✅ yes / sim |
| captcha_mr8h1qt6_auto_r8ktbc.png | 34514 | 34514 | ✅ yes / sim |
| captcha_0349_Gustavo7lmq4n.png | 33953 | 33963 | ❌ no / não (1 digit / 1 dígito) |
| captcha_0099_Craftyilr3n8.png | 42919 | 42919 | ✅ yes / sim |
EN: 👁️ Truly unlabeled pool (157 collected captchas with no manual label, never used in training). Manual visual audit of the first 12:
PT: 👁️ Conjunto nunca rotulado (157 captchas coletados sem rótulo manual, nunca usados no treino). Auditoria visual manual dos 12 primeiros:
| file / arquivo | visual truth / leitura visual | pred | match |
|---|---|---|---|
| captcha_0407_Caioi63ufq.png | 74069 | 74059 | ❌ no / não (6→5) |
| captcha_0408_Novak53nwo.png | 31090 | 3109 | ❌ no / não (dropped trailing 0 / perdeu o 0 final) |
| captcha_0409_Steve1fr53v.png | 40011 | 4001 | ❌ no / não (collapsed repeat 11→1 / colapsou repetição) |
| captcha_0410_Sunnyvwxshw.png | 70829 | 70829 | ✅ yes / sim |
| captcha_0411_Lucasdqmtye.png | 23121 | 23121 | ✅ yes / sim |
| captcha_0412_Alex0c7psl.png | 50198 | 5701195 | ❌ no / não (bad split / segmentação ruim) |
| captcha_0413_Frosttftiib.png | 36602 | 36602 | ✅ yes / sim |
| captcha_0414_Stormiu5r9s.png | 97500 | 97500 | ✅ yes / sim |
| captcha_0415_Viniciusmbd4l4.png | 14108 | 14108 | ✅ yes / sim |
| captcha_0416_Luna89x7h2.png | 42512 | 42512 | ✅ yes / sim |
| captcha_0417_Sunnypwhd5k.png | 68735 | 68735 | ✅ yes / sim |
| captcha_0418_Rafael5uxazh.png | 85391 | 85391 | ✅ yes / sim |
EN: ✅ 8/12 exact on never-seen, never-labeled images; failures are typical greedy-CTC modes
(single-digit confusion, collapsed repeats like 11→1, dropped edge digits).
PT: ✅ 8/12 exatos em imagens nunca vistas e nunca rotuladas; as falhas são modos típicos do CTC guloso
(confusão de um dígito, repetições colapsadas como 11→1, dígitos de borda perdidos).
🚀 Usage / Uso
pip install -r requirements.txt
# 🖼️ single image / imagem única
python predict_captcha.py --model captcha_model.pth --image captcha.png
# 📁 directory / diretório
python predict_captcha.py --model captcha_model.pth --dir ./captchas --limit 20
As a library / Como biblioteca 📚:
from predict_captcha import CaptchaPredictor
clf = CaptchaPredictor("captcha_model.pth") # device auto: cuda if available else cpu
print(clf.predict("captcha.png"))
print(clf.predict_batch(["a.png", "b.png"]))
⚠️ Limitations / Limitações
EN:
- Fixed domain: one captcha style (overlapping wavy digits, ~5 chars). Other styles/fonts/backgrounds will degrade.
- Greedy CTC only: repeated adjacent digits (
11,00) can collapse; no beam search / language model. - Length is not enforced: outputs can be 4–7 chars on hard samples (see table above).
- ~84% exact-match on held-out data — single-digit errors are the common case, not full garbage.
- 🏢 Model developed by Confia Company for Mineflayer bots operating on Minecraft servers protected by the nAntiBot plugin.
PT:
- Domínio fixo: um estilo de captcha (dígitos ondulados sobrepostos, ~5 caracteres). Outros estilos/fontes/fundos degradam.
- Só CTC guloso: dígitos adjacentes repetidos (
11,00) podem colapsar; sem beam search / modelo de linguagem. - Comprimento não é forçado: saídas podem ter 4–7 caracteres em amostras difíceis (ver tabela acima).
- ~84% de acerto exato em dados retidos — o caso comum é erro de um dígito, não lixo completo.
- 🏢 Modelo desenvolvido pela Confia Company para bots Mineflayer usados em servidores de Minecraft com o plugin nAntiBot.