分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 软件开发

Aforge.net识别简易数字验证码问题

发布时间:2023-09-06 01:52责任编辑:蔡小小关键词:验证码

参考: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 == 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(); ???????????????????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[0]); ???????????int last = Convert.ToInt32(lls[2]); ???????????int result = 0; ???????????if (lls[1] == "-") ???????????{ ???????????????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 = 0; i < bmp.Width; i++) ???????????{ ???????????????for (int j = 0; 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 = 0; ???????????for (int i = 0; i < bmp.Width; i++) ???????????{ ???????????????for (int j = 0; j < bmp.Height; j++) ???????????????{ ???????????????????Color color = bmp.GetPixel(i, j); ???????????????????average += color.B; ???????????????} ???????????} ???????????average = 60; ???????????for (int i = 0; i < bmp.Width; i++) ???????????{ ???????????????for (int j = 0; j < bmp.Height; j++) ???????????????{ ???????????????????//获取该点的像素的RGB的颜色 ?????????????????????Color color = bmp.GetPixel(i, j); ???????????????????int value = 255 - color.B; ???????????????????Color newColor = value > average ? Color.FromArgb(0, 0, 0) : Color.FromArgb(255, 255, 255); ???????????????????bm.SetPixel(i, j, newColor); ???????????????} ???????????} ???????????return bm; ???????} ???????/// <summary> ???????/// 重置图片的指定大小并且居中 ???????/// </summary> ???????/// <param name="list"></param> ???????/// <returns></returns> ???????public List<Bitmap> ToResizeAndCenterIt(List<Bitmap> list, int w = 20, int h = 20) ???????{ ???????????List<Bitmap> resizeList = new List<Bitmap>(); ???????????for (int i = 0; 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], 0, 0); ???????????????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(0, 0, 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) / 2; ???????????????int centerY = (h - sh) / 2; ???????????????var bnew2 = new Bitmap(list[i].Width, list[i].Height, PixelFormat.Format24bppRgb); ???????????????Graphics g2 = Graphics.FromImage(bnew2); ???????????????g2.DrawImage(list[i], 0, 0); ???????????????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 = 0; x < b.Width; x++) ???????????{ ???????????????for (int y = 0; y < b.Height; y++) ???????????????{ ???????????????????//获取当前像素点像素 ???????????????????var pixel = b.GetPixel(x, y); ???????????????????//说明是黑色点 ???????????????????if (pixel.R == 0) ???????????????????{ ???????????????????????cols[x] = ++cols[x]; ???????????????????} ???????????????} ???????????} ???????????int left = 0, right = 0; ???????????for (int i = 0; i < cols.Length; i++) ???????????{ ???????????????//说明该列有像素值(为了防止像素干扰,去噪后出现空白的问题,所以多判断一下,防止切割成多个) ???????????????if (cols[i] > 0 || (i + 1 < cols.Length && cols[i + 1] > 0)) ???????????????{ ???????????????????if (left == 0) ???????????????????{ ???????????????????????//切下来图片的横坐标left ???????????????????????left = i; ???????????????????} ???????????????????else ???????????????????{ ???????????????????????//切下来图片的横坐标right ???????????????????????right = i; ???????????????????} ???????????????} ???????????????else ???????????????{ ???????????????????//说明已经有切割图了,下面我们进行切割处理 ???????????????????if ((left > 0 || right > 0)) ???????????????????{ ???????????????????????Crop corp = new Crop(new Rectangle(left, 0, right - left + 1, b.Height)); ???????????????????????var small = corp.Apply(b); ???????????????????????//居中,将图片放在20*50的像素里面 ???????????????????????list.Add(small); ???????????????????} ???????????????????left = right = 0; ???????????????} ???????????} ???????????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 = 0; y < segb.Height; y++) ???????????????{ ???????????????????for (int x = 0; x < segb.Width; x++) ???????????????????{ ???????????????????????//获取当前像素点像素 ???????????????????????var pixel = segb.GetPixel(x, y); ???????????????????????//说明是黑色点 ???????????????????????if (pixel.R == 0) ???????????????????????{ ???????????????????????????rows[y] = ++rows[y]; ???????????????????????} ???????????????????} ???????????????} ???????????????int bottom = 0, top = 0; ???????????????for (int y = 0; y < rows.Length; y++) ???????????????{ ???????????????????//说明该行有像素值(为了防止像素干扰,去噪后出现空白的问题,所以多判断一下,防止切割成多个) ???????????????????if (rows[y] > 0 || (y + 1 < rows.Length && rows[y + 1] > 0)) ???????????????????{ ???????????????????????if (top == 0) ???????????????????????{ ???????????????????????????//切下来图片的top坐标 ???????????????????????????top = y; ???????????????????????} ???????????????????????else ???????????????????????{ ???????????????????????????//切下来图片的bottom坐标 ???????????????????????????bottom = y; ???????????????????????} ???????????????????} ???????????????????else ???????????????????{ ???????????????????????//说明已经有切割图了,下面我们进行切割处理 ???????????????????????if ((top > 0 || bottom > 0) && bottom - top > 0) ???????????????????????{ ???????????????????????????Crop corp = new Crop(new Rectangle(0, top, segb.Width, bottom - top + 1)); ???????????????????????????var small = corp.Apply(segb); ???????????????????????????corplist.Add(small); ???????????????????????} ???????????????????????top = bottom = 0; ???????????????????} ???????????????} ???????????} ???????????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 - 5).Substring(0, 1); }).ToList(); ???????????var result = new List<string>(); ???????????ExhaustiveTemplateMatching templateMatching = new ExhaustiveTemplateMatching(0.9f); ???????????//这里面有四张图片,进行四张图的模板匹配 ???????????for (int i = 0; i < 3; i++) ???????????{ ???????????????float max = 0; ???????????????int index = 0; ???????????????for (int j = 0; j < templateList.Count; j++) ???????????????{ ???????????????????var compare = templateMatching.ProcessImage(list[i], templateList[j]); ???????????????????if (compare.Length > 0 && compare[0].Similarity > max) ???????????????????{ ???????????????????????//记录下最相似的 ???????????????????????max = compare[0].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识别简易数字验证码问题

原文地址:https://www.cnblogs.com/wangzhenghua/p/8994305.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved