ORC e Redes Neurais em JavaScript
7/4/2009 | Tags:, , , , , , | Escrito por: Dirceu Pauka Jr.

Esse texto é uma tradução do “OCR and Neural Nets in JavaScript” escrito por John Resig.


Um belo pedaço de JavaScript foi criado ontem. É um script para GreaseMonkey escrito por ‘Shaun Friedle‘ que resolve automaticamente o captcha do Megaupload. Existe uma demonstração online caso você queira dar uma olhada.

Atualmente os captchas usados no Megaupload não são muito “difíceis” de resolver (de fato eles são muito ruins – exemplos abaixo).

captchacaptchacaptcha

Existem porém pontos interessantes aqui:

  • A API getImageData do HTML 5 é usada para pegar informações sobre os pixels da imagem. No HTML 5 é permitido adicionar uma imagem no elemento canvas (de onde então pose-se extrair informações sobre cada pixel usando JavaScript).
  • O script implementa uma rede neural, escrita em puro JavaScript.
  • As informações do pixel, extraídas da imagem usando canvas, são jogadas dentro da rede neural em uma tentativa de adivinhar o caractere usado – algo parecido com Optical Character Recognition (OCR).

Se abrirmos o código fonte podemos perceber que o funcionamento recai em como o captcha é implementado. Como mencionado anteriormente esse não é um captcha muito bom. Ele tem 3 letras, cada uma em uma cor diferente, usando uma possibilidade de 26 caracteres e eles são todos do mesmo tipo gráfico.

O primeiro passo é fácil de entender: O captcha é copiado dentro do canvas e então convertido para escala de cinza.

image_data.data[i] = luma;
image_data.data[i+1] = luma;
image_data.data[i+2] = luma;
image_data.data[i+3] = 255;
}
}
}

O canvas é então quebrado em três matrizes de pixels - cada uma contendo um caractere (isso é bem fácil de fazer - uma vez que cada caractere é de uma cor diferente, eles são separados pela diferença de cores usadas).

// Muda todos pixels de tal cor para a cor branca
if (image_data.data[i] == colour) {
image_data.data[i] = 255;
image_data.data[i+1] = 255;
image_data.data[i+2] = 255;
} else { // Todo o resto vira preto
image_data.data[i] = 0;
image_data.data[i+1] = 0;
image_data.data[i+2] = 0;
}
}
}
}

Finalmente qualquer pixel solto é removido da imagem (retornando um caractere limpo). Isso é feito procurando por pixels brancos (que eram da cor da letra) que são cercados de preto (que não bateram com nenhuma cor de letra). Se esse for o caso o pixel é simplesmente removido.

if (image_data.data[i] == 255 &&
image_data.data[above] == 0 &&
image_data.data[below] == 0) {
image_data.data[i] = 0;
image_data.data[i+1] = 0;
image_data.data[i+2] = 0;
}

Estamos bem próximos de ter uma forma que pode alimentar uma rede neural, mas não estamos lá ainda. O script agora vai fazer uma forma bem crua de detecção de borda na forma, procurando pelos pixels que cercam o caractere e então o transformando em um retângulo. Nesse trecho a matriz também é reduzida para 20 por 25 pixels.

image_data[i] = cropped_canvas.getContext("2d").getImageData(0, 0,
cropped_canvas.width, cropped_canvas.height);

Então, após todo esse trabalho, o que nós temos? Uma matriz de 20 por 25 pixels contendo um único retângulo preenchido com preto e branco. Terrivelmente excitante.

Agora alguns pontos estratégicos são extraído da matriz para serem usado como "receptores" (eles que alimentarão a rede neural). Como exemplo, o receptor deve olhar para o pixel da posição 9x6 e verificar se ele está "ligado" ou não. Somente 64 estados (muito menos do que a matriz de 20 por 25 inteira) são então jogados para dentro da rede neural.

A questão que você deve estar se perguntando agora é: Por que não fazer somente uma simples comparação de pixels? Por que "isso de" redes neurais? Bom, o problema é que com toda essa redução da informação um monte de ambiguidade existe. Se você rodar a demonstração do script vai perceber que a comparação simples de pixels vai falhar mais que a nossa rede.

A próxima etapa é tentar adivinhar a letra. A rede é então alimentada com 64 valores boleanos (coletados das letras) juntamente com uma serie de valores pre-computados. Um dos conceitos por trás do funcionamento de redes neurais é que você reutiliza valores de execuções anteriores. É como se o autor do script rodasse ele várias vezes e coletasse uma serie de resultados para conseguir um valor ótimo. O resultado em si não tem nenhuma funcionalidade por si só mas ele ajuda a derivar o valor final.

A rede neural utiliza os 64 valores extraídos dos caracteres do captcha para comparar com valores pré-computados de cada letra do alfabeto. O resultado retornado dessas comparações é parecido com ‘98% de chances para A’, ‘36% de chances para B’, etc..

Repetindo com todas letras do captcha o objetivo é atingido. Ele não é 100% perfeito (imagino que resultados melhores seriam alcançados se a letra não fosse transformada em um simples retângulo antes da execução do algoritmo) mas é bom pelo que é – e impressionante considerando que tudo acontece 100% no navegador usando padrões emergentes.

Como nota – o que acontece aqui é bem especifico para esse captcha. Essa técnica deve funcionar em mais alguns captchas mal implementados, mas além disso a complexidade da maioria dos captchas é muito avançada (principalmente para qualquer analise no lado do cliente).

Eu estou esperando trabalhos interessantes derivados desse projeto – isso carrega bastante potencial.


4 Comentários so far
Leave a comment

opa! excelente o artigo!

oi eu gostaria de tirar uma duvida. para programar redes artificiais é difícil, levando em conta a aprendizagem dos neuronios artificiais.obrigado.

Na realidade a unica barreira que vejo aqui é a quantidade de neurônios e a precisão deles no sistema. Se você tiver capacidade de processamento suficiente eu diria que nenhum CAPTHA consegue impedi-lo de invadir um sistema. Não que essa seja a unica funcionalidade de redes neurais, mas como foi mostrado aqui com esse exemplo que mesmo um Javascript (lento perto de C/C++) hoje em dia consegue resolver esse tipo de problema.

Abraço!

para criar uma A.I (inteligencia artificial) como proceder. enecessario que seja um profissional.para programar em java e complicado.então me informe uma linguagem para A.I.
obrigado

TrackBack URI

Deixe um comentário
Quebras de linha e parágrafo automáticas, seu email nunca será mostrado, HTML permitido: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

(obrigatório)

(obrigatório)