`
hereson
  • 浏览: 1453784 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

【转】借助OCR和神经网络,用JavaScript识别验证码

 
阅读更多

转载自 deadpig
最终编辑 deadpig

原文作者:John Resig
原文链接:OCR and Neural Nets in JavaScript
译者:七月佑安

【原文标题】OCR and Neural Nets in JavaScript
【原文作者】John Resig
昨天发现的了一段非常令人惊奇的JavaScript代码,是由ShaunF编写的automatically solves captchas,一个专门应用在Megaupload网站的Greasemonkey脚本。如果你要亲自尝试一下,可以先看看这个演示。而这个脚本的作用,正如名字所示,可以识别这个网站的验证码。
现在,这个网站的验证码已经不是个什么难题了。(实际上,这是一个本来设计的就不怎么好的验证码,下面会给出一些例子)
对于这段脚本,我们有很多值得注意的事情:
  1. Canvas可以将图片嵌入到画布上,而getImageData函数可以从画布上获取验证码的像素数据。
  2. 这个脚本完全用JavaScript编写了一套神经网络的实现。
  3. 通过Canvas从图片获取的像素数据,被传入神经网络,通过OCR技术来获取图片中所表示的真实字符。
如果我们翻开源代码,就会发现这个脚本究竟是如何实现的,我们也可以领会这个验证码究竟是如何实现的。就像我之前提到的,这个验证码设计的本身就不好,只有3个字母,而且还用不同的颜色区分,只包含26个字母,最主要的,他们始终是同一字体。
第一个步骤很明确:把验证码的像素图像复制到Canvas中,并且转换为灰度模式。
function convert_grey(image_data){
for(var x = 0; x <image_data.width; x++){
for(var y = 0; y <image_data.height; y++){
var i = x*4+y*4*image_data.width;
var luma = Math.floor(image_data.data[i] * 299/1000 +
image_data.data[i+1] * 587/1000 +
image_data.data[i+2] * 114/1000);

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

接下来Canvas被分解成3个独立的像素矩阵,每个矩阵都包含一个字母。(按道理来说,这是非常容易的事情。每个字母都由不同颜色组成,可以直接用颜色区分不同的字母。)
filter(image_data[0]105);
filter(image_data[1]120);
filter(image_data[2]135);
function filter(image_data, colour){
for(var x = 0; x <image_data.width; x++){
for(var y = 0; y <image_data.height; y++){
var i = x*4+y*4*image_data.width;

// Turn all the pixels of the certain colour to white
if(image_data.data[i] == colour){
image_data.data[i] = 255;
image_data.data[i+1] = 255;
image_data.data[i+2] = 255;

// Everything else to black
}else{
image_data.data[i] = 0;
image_data.data[i+1] = 0;
image_data.data[i+2] = 0;
}
}
}
}

然后最后,为了得到一个清晰的字母,我们还要把那些不相干的噪声像素从图片上去除。具体的方法,先要找到那些前面或者后面被黑色(之前没有匹配的像素)包裹的白色像素(之前已经匹配的像素),如果找到这样的像素,就简单的把它门直接删除。
var i = x*4+y*4*image_data.width;
var above = x*4+(y-1)*4*image_data.width;
var below = x*4+(y+1)*4*image_data.width;

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;
}

我们现在已经得到了非常接近的图形,但还不够明确。脚本接下来会检测出这些形状的边缘,具体的是要找到图形中最上面、最下面、最左面和最右面的像素,然后把图形转换成矩形,最后将矩形的数据转换为一个20*25的矩阵。
cropped_canvas.getContext("2d").fillRect(002025);
var edges = find_edges(image_data[i]);
cropped_canvas.getContext("2d").drawImage(canvas, edges[0], edges[1]
edges[2]-edges[0], edges[3]-edges[1]00
edges[2]-edges[0], edges[3]-edges[1]);

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

最后,我们得到了什么?一个20*25的矩阵,里面包含着一个绘制着黑白两种颜色像素的矩形,真是令人兴奋啊。
矩形被进一步的缩小。一些关键位置的像素以接受体(receptors)的状态被提取出来,这些接受体最终会被传入神经网络。举例而言,某个接受体具体对应的可能是位于9*6位置像素的状态,有像素或者没有像素。脚本会提取一系列这样的状态(远少于对20*25矩阵整个计算的次数 - 只提取64种状态),并将这些状态传入神经网络。
你可能要问,为什么不直接对像素进行比较?为什么还要和神经网络扯在一起?问题的关键在于,我们要去掉那些模棱两可的情况。如果你试过了之前提到的演示就会发现,直接进行像素比较比通过神经网络比较,更容易出现偶尔判断错误的情况。但我们必须承认,对于大部分用户来说,直接的像素比较应该已经足够了。
下一个步骤就是尝试猜字母了。神经网络中传入了64个布尔值(由其中的一个字母图像获取而来),同时包含一系列预先计算好的数据。神经网络的理念之一,就是我们首先要知道希望得到什么结果。很可能脚本的作者反复的运行脚本,并收集了一系列最佳评分,这些评分可能包含这样的含义:“如果9*6位置存在像素,那么有58%的可能是字母A”。
当神经网络对验证码中一个字母对应的64个布尔值进行计算以后,和一个预先计算好的字母表相比较,然后为和每个字母的匹配都给出一个分数。(最后的结果可能类似:98%的可能是字母A,36%的可能是字母B等)
当对验证码中的三个字母都经过了计算以后,最终的结果也就出来了。确定的是,肯定不是100%精确的(不知道如果在开始的时候不将字母转换成矩形,是不是可以提高评分的精度),但这已经相当好了,至少对于当前的用途来说。而且所有的操作都是在浏览器中,通过基于标准的客户端技术实现的,这不是很神奇么?

补充说明一下,这个脚本应该算是一个特例吧,这项技术可能会应用在更多设计不良的验证码上,但对于更多设计复杂的验证码来说,就有点力不从心了(尤其是这种基于客户端的分析)。

我非常期待能有更多人从这个项目中得到灵感,开发出更多有意思的东西来,它的潜力太巨大了。

分享到:
评论

相关推荐

    OCRServer识别验证码.zip

    5. 分类识别:利用预先训练的分类器(如SVM、神经网络等)对特征向量进行分类,得出识别结果。 二、OCRServer验证码识别流程 OCRServer在处理验证码时,会依据上述步骤进行操作。具体流程包括: 1. 图片上传:用户...

    jmeter-jmeter使用ocrserver工具自动识别验证码配置

    jmeter使用ocrserver工具自动识别验证码配置

    Umi-OCR识别验证码

    接下来,会运用特定的OCR模型,如深度学习的卷积神经网络(CNN)或循环神经网络(RNN),训练出能够识别不同字体、形状和背景的验证码模型。训练数据通常包括大量已知的验证码图片及其对应的文本标签。 在实际应用...

    DELPHI本地识别验证码 易语言 OCR DLL

    在这个过程中,OCR软件可能使用了机器学习算法,如神经网络,来提高识别的准确率。 OCR DLL的创建者可能已经训练了一个模型,使其能够处理常见的验证码样式,包括扭曲、变形、噪声和背景干扰等。DLL文件`ocr.dll`...

    Java使用OCR技术识别验证码实现自动化登陆方法

    在本篇文章里小编给大家分享的是关于Java 如何使用 OCR 技术识别验证码实现自动化登陆的相关知识点内容,需要的朋友们学习下。

    使用Java调用Ocr识别验证码

    总的来说,这个资源包提供了Java环境下使用Tesseract OCR识别验证码的基础,开发者可以根据提供的代码示例和使用说明进行实践,结合自己的需求进行定制和优化。理解并熟练掌握这些知识点,对于提升自动化工具的效能...

    ocr识别验证码工具

    `不调用dll识别验证码.e`、`ocr的dll源程序.e`和`调用ocr的dll识别.e`这三份文件可能是源代码或工程文件,它们提供了关于如何利用`my_ocr.dll`进行验证码识别的详细步骤。源代码可能包含了调用DLL函数的方法,以及...

    非常好验证码自动识别代码-C# OCR光学识别数字识别率达100

    总的来说,C# OCR验证码识别技术结合了图像处理、模式识别和机器学习,为自动化处理验证码提供了可能。通过不断优化和调整,可以有效提升验证码的识别效率和准确率,但也需要注意验证码安全性的平衡,防止被恶意利用...

    c# 验证码识别 OCR图片识别 准确率非常高

    4. 分类识别:利用机器学习算法(如支持向量机SVM、神经网络或深度学习模型)训练模型,使模型能根据提取的特征识别出字符。训练数据通常包含大量的已知验证码图像及其对应的正确字符。 5. 结果后处理:识别出的...

    OCR验证码识别C#代码

    4. **模式识别**:使用机器学习算法(如SVM、神经网络)训练模型,让其学习不同字符的特征。C#中的ML.NET库可以用来创建这样的模型。 5. **OCR引擎**:利用训练好的模型进行字符识别。C#中可以使用Tesseract OCR,...

    OCR自动识别验证码

    验证码自动识别技术是一种基于图像处理和机器学习的计算机视觉任务,它主要用于网络安全,防止恶意自动化操作,例如垃圾邮件发送、机器人注册等。OCR(Optical Character Recognition)即光学字符识别,是这项技术的...

    JAVA智能验证码识别,可训练识别率高

    3. 训练模型:使用大量的已知验证码样本对OCR引擎进行训练,通过机器学习算法如SVM(支持向量机)或神经网络来提升识别精度。 4. 干扰线处理:针对带干扰线的验证码,可以利用形态学操作(如腐蚀和膨胀)去除线条,...

    Python-用opencv2tesseractocr和一些机器学习算法识别验证码

    用opencv2,tesseract-ocr和一些机器学习算法识别验证码

    OCR识别技术验证码识别程序

    在本案例中,“OCR识别技术验证码识别程序”是一个专门针对动网验证码的解决方案,它利用OCR技术来解析和识别动网论坛系统的验证码图片,从而实现自动化处理。 验证码的主要目的是防止自动化的机器人或恶意软件进行...

    OCR识别验证码技术.zip

    例如,使用深度学习模型如卷积神经网络(CNN)可以训练出更强大的识别能力,通过大量标注数据来学习各种扭曲和变形的字符。 VC,可能是Visual C++的简称,这是一种由Microsoft开发的集成开发环境,常用于创建...

    java 验证码识别 OCR

    java 验证码识别 OCR。

    tesseract-ocr和pytesseract识别验证码

    验证码识别在信息技术领域中是一项重要的任务,特别是在网络安全和自动化测试中。Tesseract OCR(Optical Character Recognition)是一款由Google维护的开源OCR引擎,它能够识别图像中的文本,并将其转换为可编辑的...

    OCR识别验证码

    4. **模型训练**:可以使用机器学习算法(如SVM、神经网络等)训练模型,使其能够根据提取的特征识别字符。训练数据集通常包含大量已标注的验证码图像。 5. **识别算法**:使用训练好的模型对新验证码进行识别,将...

    jmeter识别图片验证码的包

    总结来说,这个压缩包提供的是一种利用OCR技术在JMeter中识别图片验证码的方法,尽管存在识别率不高的问题,但通过合理配置和优化,依然可以在一定程度上提升自动化测试的效率。实际应用时,需要根据具体需求和...

    ocr网站验证码识别引擎

    4. 字符识别:利用深度学习模型(如卷积神经网络CNN或循环神经网络RNN),结合训练集上的大量样本,对每个字符进行分类识别。 5. 后处理:最后,通过上下文信息、字符组合规则等,对识别结果进行校验和优化,提高...

Global site tag (gtag.js) - Google Analytics