Scarnox · Blog

OCR de captcha de imagem e texto: como ler captchas distorcidos

Um captcha de imagem mostra uma sequência curta de letras ou dígitos como uma figura, às vezes com ruído, rotação e linhas onduladas. O reconhecimento óptico de caracteres (OCR) consegue ler versões simples desses captchas com um motor de código aberto, como o Tesseract. A precisão depende de quão limpa está a imagem, então a maior parte do trabalho é pré-processamento. Este guia mostra uma configuração funcional em Python, explica onde ela falha e deixa uma coisa clara: a API ativa da Scarnox resolve tokens de widgets PopularCaptcha, não captchas de imagem para texto. Planeje o OCR como código seu, e não como uma chamada de API.

Quando o OCR funciona e quando não funciona

O OCR é uma primeira tentativa razoável quando o texto está:

Ele tem dificuldade com letras rotacionadas, letras que se tocam, texturas de fundo e linhas desenhadas sobre os glifos. Cada um desses casos exige uma etapa de pré-processamento específica, e alguns exigem um modelo totalmente diferente. Esteja preparado para medir a precisão em vez de presumi-la.

Instale as ferramentas

Você precisa de Python, do binário do Tesseract e de dois pacotes Python:

pip install pillow pytesseract

O Tesseract é uma instalação separada. No Windows, use o instalador do projeto Tesseract e certifique-se de que o executável está no PATH, ou aponte pytesseract.pytesseract.tesseract_cmd para ele.

Pré-processe e leia

A maior parte da precisão vem de uma entrada limpa. A sequência abaixo converte para tons de cinza, aumenta o contraste, aplica um limiar fixo, amplia a imagem e restringe a saída aos caracteres que o captcha usa:

from PIL import Image, ImageOps
import pytesseract

# Caracteres que o captcha pode usar. Deixe de fora parecidos como 0/O e 1/I se o captcha nunca os usa.
ALLOWED = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"

def read_text(path: str) -> str:
    img = Image.open(path)
    gray = ImageOps.grayscale(img)
    gray = ImageOps.autocontrast(gray)
    # Limiar fixo: pixels mais claros que 140 viram branco, o resto vira preto.
    bw = gray.point(lambda p: 255 if p > 140 else 0)
    # O Tesseract funciona melhor com glifos maiores.
    bw = bw.resize((bw.width * 3, bw.height * 3))
    config = f"--psm 7 -c tessedit_char_whitelist={ALLOWED}"  # psm 7: uma linha de texto
    return pytesseract.image_to_string(bw, config=config).strip()

if __name__ == "__main__":
    print(read_text("sample_captcha.png"))

O valor de limiar 140 é um ponto de partida. Imprima a imagem processada, compare com a original e ajuste até que as letras fiquem sólidas e o fundo limpo.

Meça a precisão antes de confiar

Uma leitura correta em uma imagem não prova nada. Salve um conjunto de captchas com respostas conhecidas, rode a função em todos e conte os acertos:

def accuracy(samples: dict[str, str]) -> float:
    # samples mapeia um caminho de arquivo para o texto verdadeiro
    hits = sum(read_text(path) == truth for path, truth in samples.items())
    return hits / len(samples)

labelled = {
    "samples/0001.png": "K7PQ2",
    "samples/0002.png": "M3XN9",
}
print(f"accuracy: {accuracy(labelled):.0%}")

Acompanhe esse número sempre que mudar o pré-processamento. Se o índice continuar baixo depois de várias mudanças, o OCR provavelmente é a ferramenta errada para esse estilo de captcha, e você deve procurar outra abordagem.

Onde ele quebra

Checklist de pré-processamento

Quando uma leitura falha, percorra estes itens na ordem. Mude uma coisa de cada vez para ver qual etapa ajudou:

  1. Verifique o tamanho da entrada. Captchas muito pequenos costumam ser lidos melhor depois de uma ampliação de 3x.
  2. Converta para tons de cinza e estique o contraste para que as letras se destaquem.
  3. Aplique um limiar e teste alguns valores antes de escolher um.
  4. Remova o ruído pontual com um filtro de mediana e, se necessário, aplique o limiar de novo.
  5. Recorte a imagem na área do texto para que o fundo não confunda o motor.
  6. Restrinja o conjunto de caracteres ao que o captcha usa.
  7. Experimente outro modo de segmentação de página se o texto estiver espalhado ou empilhado.

Mantenha a ordem e as configurações no controle de versão, junto às suas amostras rotuladas. Um pipeline de pré-processamento é código, e deve ser revisado como código.

OCR ou um modelo que você mesmo roda

O OCR clássico é rápido e roda em um notebook, mas é frágil quando o captcha muda de estilo. Modelos de imagem treinados com o seu próprio conjunto rotulado conseguem lidar com mais variação, ao custo de coletar dados e rodar inferência. Os dois são responsabilidade sua para construir e manter. Nenhum dos dois é hoje um endpoint hospedado da Scarnox, então planeje a infraestrutura antes de se comprometer com um deles.

O que a Scarnox faz e não faz aqui

A API ativa da Scarnox resolve tokens de widgets PopularCaptcha. A requisição é POST https://api.scarnox.com/api/tasks/create com um tipo de tarefa PopularCaptcha, um sitekey e uma URL de página, e a resposta é um token para o campo do formulário. É um trabalho diferente de ler o texto de uma imagem, e a Scarnox não oferece hoje um endpoint de imagem para texto. Se o seu problema é um captcha de imagem, use OCR ou um modelo que você mesmo roda, e veja os outros guias para saber o que a Scarnox cobre. Você pode criar uma conta e começar com crédito de teste grátis, sem cartão, para os fluxos de PopularCaptcha que ela suporta. A página de preços tem a tabela atual de valores.

Usos legítimos

Não use OCR para passar por um captcha em um site que não permite acesso automatizado. Captchas de imagem existem justamente para frear esse tipo de uso.

Próximos passos