参考:https://www.bbsmax.com/A/rV57LjWGdP/

https://blog.csdn.net/louislong007/article/details/47683035

简易验证码样例:

验证码识别流程:

首先进行图像获取:火狐浏览器,找到获取验证码地址,获取验证码图像,传递给类,直接获取到验证码!

验证码获取:

         /// <summary>
/// 通过GET方式获取验证码
/// </summary>
/// <param name="Url">url</param>
/// <param name="postDataStr">GET数据</param>
/// <param name="cookie">GET容器</param>
/// <returns></returns>
public void SendDataByGET1(string Url, ref CookieContainer cookie)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
if (cookie.Count == )
{
request.CookieContainer = new CookieContainer();
cookie = request.CookieContainer;
}
else
{
request.CookieContainer = cookie;
} request.Method = "GET";
request.ContentType = "text/html;charset=UTF-8"; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); MemoryStream ms = null;
using (var stream = response.GetResponseStream())
{
Byte[] buffer = new Byte[response.ContentLength];
int offset = , actuallyRead = ;
do
{
actuallyRead = stream.Read(buffer, offset, buffer.Length - offset);
offset += actuallyRead;
}
while (actuallyRead > );
ms = new MemoryStream(buffer);
} b = new Bitmap(ms); //aforge只接受像素格式为24/32bpp的像素格式图片,所以处理前,先进行格式转化
var bnew = new Bitmap(b.Width, b.Height,PixelFormat.Format24bppRgb); Graphics g = Graphics.FromImage(bnew); g.DrawImage(b, , ); g.Dispose(); pictureBox1.Image = bnew; //b = new Threshold(50).Apply(b);
response.Close(); string strCookies = request.CookieContainer.GetCookieHeader(request.RequestUri); //把cookies转换成字符串 textBox2.Text=new VerificationCodeProcess().GetVerificationCode(bnew).ToString(); //Stream myResponseStream = response.GetResponseStream();
//StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
//string retString = myStreamReader.ReadToEnd();
//myStreamReader.Close();
//myResponseStream.Close(); //MessageBox.Show(strCookies);
}

验证码处理:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
//
using System.Net;
using System.IO;
using Model;
using BLL;
using Model;
using AForge;
using AForge.Imaging;
using AForge.MachineLearning;
using System.Drawing.Drawing2D;
using AForge.Imaging.Filters; namespace EmsService
{
public class VerificationCodeProcess
{
public int GetVerificationCode(Bitmap bmp)
{
//灰度
bmp = ToGray(bmp);
// MessageBox.Show(b.PixelFormat.ToString());
//二进制//
// pictureBox3.Image = ConvertToBinaryImage(new Bitmap(pictureBox2.Image));
bmp = ConvertToBinaryImage(bmp);
// MessageBox.Show(b.PixelFormat.ToString());
//分割
List<Bitmap> bmList = ToResizeAndCenterIt(Crop_X(Crop_Y(bmp)));
//二进制化
StringBuilder sb = new StringBuilder();
List<string> lls = PP(bmList);
int top = Convert.ToInt32(lls[]);
int last = Convert.ToInt32(lls[]);
int result = ;
if (lls[] == "-")
{
result = top - last;
}
else
{
result = top + last;
}
return result;
}
/// <summary>
/// 灰度处理
/// </summary>
/// <param name="bmp"></param>
/// <returns></returns>
public Bitmap ToGray(Bitmap bmp)
{
Bitmap bm = new Bitmap(bmp.Width, bmp.Height); for (int i = ; i < bmp.Width; i++)
{
for (int j = ; j < bmp.Height; j++)
{
// 获取该点的像素的RGB的颜色
Color color = bmp.GetPixel(i, j);
// 利用公式计算灰度值
// 根据YUV的颜色空间中,Y的分量的物理意义是点的亮度,由该值反映亮度等级,
// 根据RGB和YUV颜色空间的变化关系可建立亮度Y与R、G、B三个颜色分量的对应:
// Y=0.3R+0.59G+0.11B,以这个亮度值表达图像的灰度值
int gray = (int)(color.R * 0.3 + color.G * 0.59 + color.B * 0.11);
Color newColor = Color.FromArgb(gray, gray, gray);
bm.SetPixel(i, j, newColor);
}
}
return bm;
}
/// <summary>
/// 二进制化
/// </summary>
/// <param name="bmp"></param>
/// <returns></returns>
public Bitmap ConvertToBinaryImage(Bitmap bmp)
{
Bitmap bm = new Bitmap(bmp.Width, bmp.Height);
int average = ;
for (int i = ; i < bmp.Width; i++)
{
for (int j = ; j < bmp.Height; j++)
{
Color color = bmp.GetPixel(i, j);
average += color.B;
}
}
average = ; for (int i = ; i < bmp.Width; i++)
{
for (int j = ; j < bmp.Height; j++)
{
//获取该点的像素的RGB的颜色
Color color = bmp.GetPixel(i, j);
int value = - color.B;
Color newColor = value > average ? Color.FromArgb(, , ) : Color.FromArgb(, , );
bm.SetPixel(i, j, newColor);
}
}
return bm;
}
/// <summary>
/// 重置图片的指定大小并且居中
/// </summary>
/// <param name="list"></param>
/// <returns></returns>
public List<Bitmap> ToResizeAndCenterIt(List<Bitmap> list, int w = , int h = )
{
List<Bitmap> resizeList = new List<Bitmap>(); for (int i = ; i < list.Count; i++)
{
//MessageBox.Show(list[i].PixelFormat.ToString());
//反转一下图片
var bnew10 = new Bitmap(list[i].Width, list[i].Height, PixelFormat.Format24bppRgb); Graphics g10 = Graphics.FromImage(bnew10); g10.DrawImage(list[i], , ); g10.Dispose();
list[i] = bnew10; list[i] = new Invert().Apply(list[i]); int sw = list[i].Width;
int sh = list[i].Height; Crop corpFilter = new Crop(new Rectangle(, , w, h)); list[i] = corpFilter.Apply(list[i]);
//var bnew1 = new Bitmap(list[i].Width, list[i].Height, PixelFormat.Format24bppRgb); //Graphics g1 = Graphics.FromImage(bnew1); //g1.DrawImage(list[i], 0, 0); //g1.Dispose();
//再反转回去
list[i] = new Invert().Apply(list[i]); // //计算中心位置
int centerX = (w - sw) / ;
int centerY = (h - sh) / ;
var bnew2 = new Bitmap(list[i].Width, list[i].Height, PixelFormat.Format24bppRgb); Graphics g2 = Graphics.FromImage(bnew2); g2.DrawImage(list[i], , ); g2.Dispose();
list[i] = new CanvasMove(new AForge.IntPoint(centerX, centerY), Color.White).Apply(list[i]); resizeList.Add(list[i]);
} return resizeList;
} /// <summary>
/// 按照 Y 轴线 切割
/// (丢弃等于号)
/// </summary>
/// <param name="?"></param>
/// <returns></returns>
public List<Bitmap> Crop_Y(Bitmap b)
{
var list = new List<Bitmap>(); //统计每一列的“1”的个数,方便切除
int[] cols = new int[b.Width]; /*
* 纵向切割
*/
for (int x = ; x < b.Width; x++)
{
for (int y = ; y < b.Height; y++)
{
//获取当前像素点像素
var pixel = b.GetPixel(x, y); //说明是黑色点
if (pixel.R == )
{
cols[x] = ++cols[x];
}
}
} int left = , right = ; for (int i = ; i < cols.Length; i++)
{
//说明该列有像素值(为了防止像素干扰,去噪后出现空白的问题,所以多判断一下,防止切割成多个)
if (cols[i] > || (i + < cols.Length && cols[i + ] > ))
{
if (left == )
{
//切下来图片的横坐标left
left = i;
}
else
{
//切下来图片的横坐标right
right = i;
}
}
else
{
//说明已经有切割图了,下面我们进行切割处理
if ((left > || right > ))
{
Crop corp = new Crop(new Rectangle(left, , right - left + , b.Height)); var small = corp.Apply(b); //居中,将图片放在20*50的像素里面 list.Add(small);
} left = right = ;
}
} return list;
} /// <summary>
/// 按照 X 轴线 切割
/// </summary>
/// <param name="b"></param>
/// <returns></returns>
public List<Bitmap> Crop_X(List<Bitmap> list)
{
var corplist = new List<Bitmap>(); //再对分割的图进行上下切割,取出上下的白边
foreach (var segb in list)
{
//统计每一行的“1”的个数,方便切除
int[] rows = new int[segb.Height]; /*
* 横向切割
*/
for (int y = ; y < segb.Height; y++)
{
for (int x = ; x < segb.Width; x++)
{
//获取当前像素点像素
var pixel = segb.GetPixel(x, y); //说明是黑色点
if (pixel.R == )
{
rows[y] = ++rows[y];
}
}
}
int bottom = , top = ; for (int y = ; y < rows.Length; y++)
{
//说明该行有像素值(为了防止像素干扰,去噪后出现空白的问题,所以多判断一下,防止切割成多个)
if (rows[y] > || (y + < rows.Length && rows[y + ] > ))
{
if (top == )
{
//切下来图片的top坐标
top = y;
}
else
{
//切下来图片的bottom坐标
bottom = y;
}
}
else
{
//说明已经有切割图了,下面我们进行切割处理
if ((top > || bottom > ) && bottom - top > )
{
Crop corp = new Crop(new Rectangle(, top, segb.Width, bottom - top + )); var small = corp.Apply(segb); corplist.Add(small);
}
top = bottom = ;
}
}
} return corplist;
}
//模式匹配
public List<string> PP(List<Bitmap> list)
{
var files = Directory.GetFiles(Environment.CurrentDirectory + "\\temp\\"); var templateList = files.Select(i => { return new Bitmap(i); }).ToList();
var templateListFileName = files.Select(i => { return i.Substring(i.Length - ).Substring(, ); }).ToList(); var result = new List<string>(); ExhaustiveTemplateMatching templateMatching = new ExhaustiveTemplateMatching(0.9f); //这里面有四张图片,进行四张图的模板匹配
for (int i = ; i < ; i++)
{
float max = ;
int index = ; for (int j = ; j < templateList.Count; j++)
{
var compare = templateMatching.ProcessImage(list[i], templateList[j]); if (compare.Length > && compare[].Similarity > max)
{
//记录下最相似的
max = compare[].Similarity;
index = j;
}
} result.Add(templateListFileName[index]);
}
return result;
} }
}

效果图:

/// <summary>         /// 通过GET方式获取验证码         /// </summary>         /// <param name="Url">url</param>         /// <param name="postDataStr">GET数据</param>         /// <param name="cookie">GET容器</param>         /// <returns></returns>         public void SendDataByGET1(string Url, ref CookieContainer cookie)         {             HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);             if (cookie.Count == 0)             {                 request.CookieContainer = new CookieContainer();                 cookie = request.CookieContainer;             }             else             {                 request.CookieContainer = cookie;             }
             request.Method = "GET";             request.ContentType = "text/html;charset=UTF-8";
             HttpWebResponse response = (HttpWebResponse)request.GetResponse();

MemoryStream ms = null;             using (var stream = response.GetResponseStream())             {                 Byte[] buffer = new Byte[response.ContentLength];                 int offset = 0, actuallyRead = 0;                 do                 {                     actuallyRead = stream.Read(buffer, offset, buffer.Length - offset);                     offset += actuallyRead;                 }                 while (actuallyRead > 0);                 ms = new MemoryStream(buffer);             }
             b = new Bitmap(ms);
             //aforge只接受像素格式为24/32bpp的像素格式图片,所以处理前,先进行格式转化             var bnew = new Bitmap(b.Width, b.Height,PixelFormat.Format24bppRgb);
             Graphics g = Graphics.FromImage(bnew);
             g.DrawImage(b, 0, 0);
             g.Dispose();         //    //                    ////灰度         //    Bitmap temp;         //    temp = AForge.Imaging.Image.Clone(b, b.PixelFormat);         //    b = new Grayscale(0.2125, 0.7154, 0.0721).Apply(b);         //    //二值化            // b = new Threshold(50).Apply(b);                  pictureBox1.Image = bnew;                     //b = new Threshold(50).Apply(b);             response.Close();                      string  strCookies = request.CookieContainer.GetCookieHeader(request.RequestUri); //把cookies转换成字符串
        textBox2.Text=new VerificationCodeProcess().GetVerificationCode(bnew).ToString();
             //Stream myResponseStream = response.GetResponseStream();             //StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));             //string retString = myStreamReader.ReadToEnd();             //myStreamReader.Close();             //myResponseStream.Close();
           //MessageBox.Show(strCookies);         }

Aforge.net识别简易数字验证码问题的更多相关文章

  1. selenium来识别数字验证码

    用python写一爬虫,需要模拟登陆,并且有数字验证码.通过selenium+pytesseract+PIL可以实现验证码识别并登陆.三大步: 用selenium截屏,此时截取的是整个页面的 用PIL ...

  2. [验证码识别技术]字符验证码杀手--CNN

    字符验证码杀手--CNN 1 abstract 目前随着深度学习,越来越蓬勃的发展,在图像识别和语音识别中也表现出了强大的生产力.对于普通的深度学习爱好者来说,一上来就去跑那边公开的大型数据库,比如I ...

  3. Python——pytessercat识别简单的验证码

    什么是验证码 验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computersand Humans Apart” (全自动 ...

  4. selenium破解数字验证码

    搞了半天,总算弄出来了,识别率还可以,普通的数字验证码 from selenium import webdriver from PIL import Image import pytesseract ...

  5. 爬虫(十二):图形验证码的识别、滑动验证码的识别(B站滑动验证码)

    1. 验证码识别 随着爬虫的发展,越来越多的网站开始采用各种各样的措施来反爬虫,其中一个措施便是使用验证码.随着技术的发展,验证码也越来越花里胡哨的了.最开始就是几个数字随机组成的图像验证码,后来加入 ...

  6. python利用selenium库识别点触验证码

    利用selenium库和超级鹰识别点触验证码(学习于静谧大大的书,想自己整理一下思路) 一.超级鹰注册:超级鹰入口 1.首先注册一个超级鹰账号,然后在超级鹰免费测试地方可以关注公众号,领取1000积分 ...

  7. 中文价格识别为数字 java代码

    运行效果: public class VoicePriceRecognition { private final static String NOT_HAS_PRICE_CONTENT="n ...

  8. 务必收藏备用:.net core中通过Json或直接获取图形验证码(数字验证码、字母验证码、混合验证码),有源代码全实战demo(开源代码.net core3.0)

    很多人写的博客大家看了会一知半解,不知道怎么用,应该引用什么类库或者代码不全,这样很多小白很是头疼,尤其是尝新技术更是如此.我们这边不止告诉你步骤,而且还提供开源demo.随着时间的推移,我们的dem ...

  9. PHP写的简单数字验证码

    用PHP写的随机生成的5位数字验证码 $yzm = ""; for($i=0;$i<5;$i++) { $a = rand(0,9); $yzm.= $a; } echo $ ...

随机推荐

  1. C# 关键字new用法

    1.实例化对象,执行构造函数. public class Test { public Test(string name) { Console.WriteLine(name); } } public c ...

  2. zzw原创_非root用户下安装nginx

    想自己安装nginx,又不相用到root用户. 非root用户下(本文为用户bdctool)来ngnix安装,要依赖pcre库.zlib库等, 1. 下载依赖包:下载地址 pcre(www.pcre. ...

  3. DOM 操作成本究竟有多高,HTML、CSS构建过程 ,从什么方向出发避免重绘重排)

    前言: 2019年!我准备好了 正文:从我接触前端到现在,一直听到的一句话:操作DOM的成本很高,不要轻易去操作DOM.尤其是React.vue等MV*框架的出现,数据驱动视图的模式越发深入人心,jQ ...

  4. day 06 编码and知识点总结

    1.day 05 内容回顾 dict:dic = {'name':'alex'} 增:dic['age']=21#存在就覆盖 dic.setdefault(),没有就增加 删除: pop()按照key ...

  5. Spring Boot:Spring Boot 中 Redis 的使用

    Redis 介绍 Redis 是目前业界使用最广泛的内存数据存储.相比 Memcached,Redis 支持更丰富的数据结构,例如 hashes, lists, sets 等,同时支持数据持久化.除此 ...

  6. __name__ __doc__ __package__

    __name__只有主程序调用才可以 如果自己的唯一入口被调用 if __name__ == '__main__' : 才执行下面的代码 """ 这个是format的注释 ...

  7. Python深入理解yield

    yield的英文单词意思是生产,刚接触Python的时候感到非常困惑,一直没弄明白yield的用法. 只是粗略的知道yield可以用来为一个函数返回值塞数据,比如下面的例子: def addlist( ...

  8. tensorflow estimator API小栗子

    TensorFlow的高级机器学习API(tf.estimator)可以轻松配置,训练和评估各种机器学习模型. 在本教程中,您将使用tf.estimator构建一个神经网络分类器,并在Iris数据集上 ...

  9. python 常用网站

    https://www.tutorialgateway.org/python-tutorial/

  10. 正则表达式判断QQ号格式是否正确

    #正在表达式匹配QQ号格式是否正确#QQ号假如长度为5-11位,纯为数字 import rewhile 1: qq=input("请输入QQ号:") result=re.finda ...