上一节,获取了网页验证码。这一节开始讲讲怎么识别验证码。

  2、获取36个字符的特征码

  2.1 分析验证码特征

验证码图片:

  经研究,发现该网页验证码的图片中字符是由数字和大写字母组成,每张验证码4个字符。其中由于数字0、1和和字母O和I比较接近,所以这四个字符没有出现,再加上和2比较像的字母Z一共有5个字符没有,所以出现的字符只有35个。
  验证码字符没有变形,大小一致。背景有噪点,大小不一。

  2.3验证码字符特征码必须的流程:

图片灰度化
图片二值化
图片分割
图片特征码提取

图片特征码提取参考louislong007兄弟的博文做了修改(https://blog.csdn.net/louislong007/article/details/47683035)

  2.4 图片灰度化


  图片灰度化就是利用特定算法,将彩色图片中的每一个像素点R、G、B三个颜色分量转换为相同的色值(0-255)。
   根据YUV的颜色空间中,Y的分量的物理意义是点的亮度,由该值反映亮度等级,根据RGB和YUV颜色空间的变化关系可建立亮度Y与R、G、B三个颜色分量的对应:Y=0.3R+0.59G+0.11B,以这个亮度值表达图像的灰度值。

    ''' <summary>''' 函数功能:灰度化bitmap图像''' </summary>''' <param name="bmp">bitmap对象</param>''' <returns>返回灰度化的bitmap对象</returns>Public Function ConvertToGrayImage(ByVal bmp As Bitmap) As BitmapDim bm As Bitmap = New Bitmap(bmp.Width, bmp.Height)Dim i As IntegerDim j As IntegerFor i = 0 To bmp.Width - 1For j = 0 To bmp.Height - 1Dim color As Color = bmp.GetPixel(i, j) '获取该点的像素的RGB的颜色'利用公式计算灰度值'根据YUV的颜色空间中,Y的分量的物理意义是点的亮度,由该值反映亮度等级,'根据RGB和YUV颜色空间的变化关系可建立亮度Y与R、G、B三个颜色分量的对应:'Y=0.3R+0.59G+0.11B,以这个亮度值表达图像的灰度值Dim gray As Integer = Int(color.R * 0.3 + color.G * 0.59 + color.B * 0.11)Dim newcolor As Color = Color.FromArgb(gray, gray, gray)bm.SetPixel(i, j, newcolor)NextNextReturn bmbm.Dispose()End Function

  2.5 图片二值化


  所谓二值化,就是将灰度化的图片转变为只有两种颜色的图片,即黑色(0,0,0)和白色(255,255,255)。取图片的平均灰度值,遍历图片中每一个像素点,大于该值设为白色,小于该值设为黑色。
  二值化代码:

   ''' <summary>''' 二值化已灰度化的bmp图像。''' </summary>''' <param name="bmp">已灰度化的位图</param>''' <returns>二值化后的bimmap对象</returns>Public Function ConvertToBinaryImage(ByVal bmp As Bitmap) As Bitmap '。'图像二值化:取图片的平均灰度作为阈值, 低于该值的全都为0, 高于该值的全都为255' 在进行了灰度化处理之后,图像中的每个象素只有一个值,那就是象素的灰度值。它的大小决定了象素的亮暗程度。' 为了更加便利的开展下面的图像处理操作,还需要对已经得到的灰度图像做一个二值化处理。' 图像的二值化就是把图像中的象素根据一定的标准分化成两种颜色。在系统中是根据象素的灰度值处理成黑白两种颜色。'和灰度化相似的, 图像的二值化也有很多成熟的算法。它可以采用自适应阀值法,也可以采用给定阀值法。Dim bm As Bitmap = New Bitmap(bmp.Width, bmp.Height)Dim average As Integer = 0For i = 0 To bmp.Width - 1For j = 0 To bmp.Height - 1Dim color As Color = bmp.GetPixel(i, j) '获取该点的像素的RGB的颜色average += color.B  '获取该点像素的灰度值并累加NextNextaverage = Int(average / (bmp.Width * bmp.Height))'图片平均灰度值For i = 0 To bmp.Width - 1For j = 0 To bmp.Height - 1Dim color As Color = bmp.GetPixel(i, j) '获取该点的像素的RGB的颜色Dim value As Integer = 255 - averageDim newcolor As ColorIf color.B > average Then'大于平均灰度值,则设为白点(255,255,255)newcolor = Color.FromArgb(255, 255, 255)Else'小于平均灰度值,则设为黑点(0,0,0)newcolor = Color.FromArgb(0, 0, 0)End Ifbm.SetPixel(i, j, newcolor)NextNextReturn bmbm.Dispose()End Function

  2.6 图片去噪

先看看去噪效果图片:

  2.6.1 噪点的判定

  这里由于我处理的网页验证码比较简单,只涉及到噪点的去除,没有涉及到干扰线的去除。所以下面所讲的只涉及到噪点的去除,对干扰线的去除方法网上有很多,有需要的可以自己去百度。
  我们怎么去判定噪点和字符呢?也就是噪点和字符的区别。
  从前面经过二值化处理可知,如果一个pixel是验证码或者干扰因素的一部分,那么这个pixel在二值化结果中其灰度值一定是0,即黑色;如果一个pixel是背景,则其灰度值应该是255是白色。因此对于孤立的噪点,其周围应该都是白色,或者大多数点都是白色pixel。

  2.6.2 去除噪点的方法及原理

  噪点去除的方法比较多,这里介绍比较简单的两种方法:8邻域去噪和连通域去噪。

  2.6.2.1 8邻域去噪

  原理:对一个噪点来讲,其周围的pixel应该全是白色的背景才对,准确来讲就是一个噪点pixel是黑色的并且外包的8个相邻pixel全是白色。当然,如果图片分辨率够高,一个噪点实际上可能是有很多个pixel组成,所以此时的判断条件应该放宽,即一个pixel是黑色的并且相邻的8个pixel白色的大于一个固定值,那么这个pixel就是噪点。对于不同的验证码,这个阀值是不固定的,所以在这可以设置大小,多试几次,找到最佳的阀值。
  我们看看效果:

  去噪强度是指噪点判断标准,例如,去噪强度为3,表示如果黑点周围8邻域中黑点的个数为3个或者3个以下,则判定此黑点为噪点,将其颜色设为白色(即背景色)。
  随着去噪强度的增加,噪点去除了,但是字符也被部分去除了,经对比,去噪强度为4效果较好。即便这样,字符部分仍有部分损失。
以下为8邻域去噪代码:

 Public Function RemoveNoise8Neighbours(ByVal bmp As Bitmap, ByVal number As Integer) As Bitmap 'number为去噪强度'8邻域降噪法,适合单个噪点和小噪点'这种方法类似均值滤波,不过对于每个pixel,' 不是取其周围像素的灰度平均值,'而是统计其周围像素点的灰度值为0或255的个数。'从前面经过二值化处理可知,'如果一个pixel是验证码或者干扰因素的一部分,'那么这个pixel在二值化结果中其灰度值一定是0, 即黑色;'如果一个pixel是背景, 则其灰度值应该是255是白色。'因此对于孤立的噪点, 其周围应该都是白色'所以对一个噪点来讲,其周围的pixel应该全是白色的背景才对,'准确来讲就是一个噪点pixel是黑色的并且外包的8个相邻pixel全是白色。'当然, 如果图片分辨率够高, 一个噪点实际上可能是有很多个pixel组成, '所以此时的判断条件应该放宽, '即一个pixel是黑色的并且相邻的8个pixel黑色的小于等于一个固定值, '那么这个pixel就是噪点。对于不同的验证码, 这个阀值是不固定的,'所以在这可以设置大小, 多试几次, 找到最佳的阀值。'经过测试, 8领域降噪法对于小的噪点的去除是很有效的, 而且计算量不大Dim bm As Bitmap = New Bitmap(bmp.Width, bmp.Height)'把图像的四边像素点变成白色,即(255,255,255)Dim white As Color = Color.FromArgb(255, 255, 255)For i = 0 To bmp.Width - 1 '上下边取白色bmp.SetPixel(i, 0, white)bmp.SetPixel(i, bmp.Height - 1, white)NextFor j = 0 To bmp.Height - 1 '左右边取白色bmp.SetPixel(0, j, white)bmp.SetPixel(bmp.Width - 1, j, white)Next'某点的相邻点为白色,而此点为黑色,删除黑点For i = 0 To bmp.Width - 1For j = 0 To bmp.Height - 1Dim color As Color = bmp.GetPixel(i, j) '获取该点的像素的RGB的颜色Dim count As Integer = 0If color.B = 0 Then '发现黑点(0,0,0)For m = i - 1 To i + 1For n = j - 1 To j + 1Dim colorneighbour As Color = bmp.GetPixel(m, n)If colorneighbour.B = 0 Then '在某黑点的相邻8点中发现黑点count += 1End IfNextNextEnd IfIf count <= number Thenbm.SetPixel(i, j, white) ' 如果黑点周围的黑点不超过number,则把黑点变成白点Elsebm.SetPixel(i, j, color)End IfNextNextReturn bmEnd Function
  2.6.2.2 连通域去噪

  原理:字符是由很多个黑色像素点组成的一大片连通域,而噪点是黑色像素点组成的一小片连通域。连通域去噪就是将小面积(即黑色像素点的个数)的连通域去掉(背景色化),保留面积较大的连通域(字符区域)。
看看效果:

  通过以上,字符面积在50到100之间。也就是说,连通域面积小于50的都可以认定为噪点,可以去除。其实,这个例子中,噪点面积最大也没有超过10。
  从效果对比来看,连通域去噪字符部分没有损失,而8邻域去噪,字符部分会有损失,可能会影响验证码的识别。所以这里我选择了连通域去噪方法去噪。
连通域去噪代码:

'' <summary>''' 二值化图片的连通域去噪,前景颜色为(0,0,0),背景颜色为(255,255,255)。函数返回去噪后的bitmap对象。''' 此函数采用自定义漫水填充法(mxdFloodFill,利用种子填充原理)。''' </summary>''' <param name="bmp">二值化bitmap对象</param>''' <param name="area">连通域面积(像素点个数)此参数可选,默认为0,不去噪</param>''' <returns></returns>Public Function RemoveNoiseConnectedRegion(ByVal bmp As Bitmap, Optional ByVal area As Integer = 0) As Bitmap '二值化图片连通域去噪Dim bm As Bitmap = bmpDim Cr As IntegerCr = 1If area <> 0 ThenFor x = 0 To bm.Width - 1For y = 0 To bm.Height - 1If bmp.GetPixel(x, y) = Color.FromArgb(0, 0, 0) Then '发现黑点Dim p As Pointp.X = xp.Y = ymxdFloodFill(bm, p, Color.FromArgb(Cr, Cr, Cr)) 'FloodFill each point in connect area using different colorCr += 1End IfNextNextDim ColorCount(255) As Integer  'caculate the area of each area For x = 0 To bm.Width - 1For y = 0 To bm.Height - 1If bm.GetPixel(x, y) <> Color.FromArgb(255, 255, 255) ThenColorCount(bm.GetPixel(x, y).B) += 1End IfNextNext'get rid of noise domain(<= area)For x = 0 To bm.Width - 1For y = 0 To bm.Height - 1If ColorCount(bm.GetPixel(x, y).B) <= area Thenbm.SetPixel(x, y, Color.FromArgb(255, 255, 255)) '如果这种颜色的domain小于阈值,则将其设为白色,即背景色,除掉。Elsebm.SetPixel(x, y, Color.FromArgb(0, 0, 0)) '否则认为它是字符区域的点,设为黑色。End IfNextNextEnd IfReturn bmEnd Function

自定义泛水填充函数代码,详细内容可参考我的博客《 vb.net 自定义的FloodFill函数(泛水填充)》

  Public Function mxdFloodFill(ByVal bm As Bitmap, ByVal SeedPoint As Point, ByVal Cr As Color) As Boolean 'seed-fill,4-neighbours,以种子点颜色相同的连通区域进行填充。' a、将B(x,y)作为种子(像素位置),并赋予其一个label,然后将该种子相邻的所有前景像素都压入栈中;' b、弹出栈顶像素,赋予其相同的label,然后再将与该栈顶像素相邻的所有前景像素都压入栈中;' c、重复b步骤,直到栈为空;' 此时, 便找到了图像B中的一个连通区域, 该区域内的像素值被标记为label;Dim newColor As Color = CrDim seedColor As Color = bm.GetPixel(SeedPoint.X, SeedPoint.Y)Dim StackSeed As New StackDim FourNeighbours As List(Of Point)If SeedPoint.X > bm.Width - 1 Or SeedPoint.Y > bm.Height - 1 ThenReturn FalseExit FunctionEnd IfStackSeed.Push(SeedPoint)Do While StackSeed.Count <> 0Dim PopSeed As Point = StackSeed.PopFourNeighbours = GetFourNeighbourSeeds(bm, PopSeed) '上下左右四邻点For Each point In FourNeighboursIf Not StackSeed.Contains(point) ThenStackSeed.Push(point)End IfNextbm.SetPixel(PopSeed.X, PopSeed.Y, newColor)LoopReturn TrueEnd Function

未完待续!

网页验证码识别实例VB.NET2019(二)相关推荐

  1. PHP验证码识别实例

    PHP验证码识别实例 PHP验证码识别实例,识别的过程包括对图像的二值化.降噪.补偿.切割.倾斜矫正.建库.匹配,最后会提供实例代码,能够直接运行识别. 简述 要识别的验证码相对比较简单,没有粘连字符 ...

  2. 韩服 永恒之塔 验证码识别实例测试[非商业用途]

    韩服 永恒之塔 验证码识别实例 韩服 永恒之塔外挂 过验证码必备工具 外挂必用 永恒之塔 验证码识别率90%以上

  3. python反爬虫应对之借助平台超级鹰突破网页验证码识别

    在爬虫过程中,有些网页需要登录才能获取里面的数据,在大部分的登录过程中,都会需要一个叫验证码识别,目前的网页有各种各样的验证码,有数字加字母的组合,有物品识别等等 在代码进行网页爬取过程中,如果由人为 ...

  4. selenium项目实战(三):实现网页验证码识别

    步骤 截屏整个页面 获得验证码坐标数据 根据坐标数据抠图 使用pytesseract模块进行验证 问题: 利用save_screenshot和PIL模块的crop截取验证码区域时,截取不到正确的二维码 ...

  5. VBS识别网页验证码

    本例演示使用VBScript对简单规则的图形验证码进行识别,先对图片进行二值化处理,此时图片成为了一张黑白图,然后对图片背景去噪,去除干扰像素,再对字符进行分离,最后把分离出的每个字符和标准字典进行对 ...

  6. 验证码识别的原理python_Python验证码识别处理实例

    一.准备工作与代码实例 1.PIL.pytesser.tesseract (1)安装PIL:下载地址:http://www.pythonware.com/products/pil/(CSDN下载) 下 ...

  7. 牛逼了啊!用 JS 实现了识别网页验证码的功能!

    点击上方 前端Q,关注公众号 回复加群,加入前端Q技术交流群 作者:LeoNaN https://zhuanlan.zhihu.com/p/28483558 很高兴大家喜欢!Github:leonof ...

  8. 验证码按钮的html代码,验证码识别-网页操作-脚本手册-VG自动化神器 - 原VG浏览器,VG网页操作神器...

    一. 功能介绍 对网页上出现的验证码进行处理,可以由用户手动输入验证码,也可以自动识别验证码. 二. 配置验证码 对网页上出现的验证码进行处理,可以由用户手动输入验证码,也可以自动识别验证码. 在使用 ...

  9. 太赞了!用 JS 实现了识别网页验证码的功能!

    点击上方蓝字关注前端瓶子君,从此前端进阶不再难 文章转载自:LeoNaN,文末有原文链接. 很高兴大家喜欢!Github:leonof/imgRecJs[1],刚刚上传,代码还需要完善-因为有不少同学 ...

  10. VB数据库经典实例总结(二)

    大家先看一张似图非图的图. 我们先称它为"过程"也许有不对的地方,在我学数据库到这个阶段.到这个刚刚接触.初生牛犊不怕虎的阶段对它的理解是这样的.所有的都是这个过程.只是在这中间掺 ...

最新文章

  1. mysql 5.7 gtid 主从_MySQL 5.7基于GTID的主从复制实践
  2. 网络摄像头实时获取信息
  3. 调试opencv程序显示应用程序无法正常启动,0xc000007b
  4. 工业交换机和工业级光纤收发器的区别
  5. Android Studio Gradle两种更新方式
  6. 王淮经验谈:我的码农原则
  7. Java:输出“水仙花数”
  8. 数据:42家公司持有超135万枚BTC 价值逾650亿美元
  9. c语言,成绩输出直方图,编写一个程序,打印输入中单词长度的直方图
  10. 各种常用浏览器 油猴脚本 插件 下载地址合集
  11. Hbase 的Java API 操作
  12. 富文本带图片导出word
  13. python3图片文字识别
  14. 中国股票市场化整为零,然后聚沙成塔
  15. php Y2K38 漏洞解决方法
  16. python gpio 接口_树莓派python中gpio库有哪些
  17. JSON解析错误:无法构建内部类的实例
  18. 高德地图搜索附近地址所遇到的问题
  19. phpstudy_pro启动mysql后循环停止又重启
  20. blur表单验证方式

热门文章

  1. 看看别人家的神仙公司
  2. ruby语言学习-开启篇
  3. 2021年安全生产模拟考试(建筑起重信号司索工模拟考试题库)安考星
  4. WordPress博客自媒体主题:Autumn
  5. OSChina 周二乱弹 ——普通高等男友招生考试
  6. Python爬虫实战之抓取猫眼电影
  7. oak深度相机入门教程-Full FOV NN
  8. apache、iis6、ii7独立ip主机屏蔽拦截蜘蛛抓取(适用vps云主机服务器)
  9. 100人PJ?へへ。バージョン1.0の反省書を書かなければなりません、今日。
  10. 【云速建站】域名配置指导