自动投票系统【三】验证码识别

    技术2022-05-20  77

         确实有很多的识别技术,我也要加强。我现在的程式只能够识别简单的数字,难点的就不能够咯。所以还要多学习,加油!

    实现步骤,

     public string getValidCode() { string s = "NO"; //验证码地址 string ValidateCodeUrl = "http://www.m-photos.cn/Inc/ChkCode/validatecode.asp";/ HttpWebResponse resp; HttpWebRequest req = (HttpWebRequest)HttpWebRequest.CreateDefault(new Uri(ValidateCodeUrl)); req.CookieContainer = ck; req.Timeout = 150000;//毫秒 resp = (HttpWebResponse)req.GetResponse(); //得到验证码图片 Bitmap bitmap = new System.Drawing.Bitmap(resp.GetResponseStream()); if (bitmap == null) { // return; } //分析得到验证码 int[] Key = GetKey(bitmap); bitmap.Clone(); bitmap.Dispose(); string ValidCode = ""; for (int i = 0; i < Key.Length; i++) { ValidCode += Key[i].ToString(); } s = ValidCode;//"OK"; return s; } 当然主要的代码在GetKey(bitmap)该函数就是读取读取返回验证码信息。请看代码: #region 分析图片 /// <summary> /// 图像切割 /// </summary> public int[] GetKey(Bitmap bitmap) { //宽度 int width = bitmap.Width; //高度 int height = bitmap.Height; //图像转化为黑白 bitmap = ConvertToGrayscale(bitmap); int[,] xArray = new int[4, 2];//4个验证码起始x坐标 int[,] yArray = new int[4, 2];//4个验证码起始y坐标 //初始化验证码起始坐标 for (int i = 0; i < 4; i++) { for (int j = 0; j < 2; j++) { xArray[i, j] = 0; yArray[i, j] = 0; } } int isStart = 0;//是否开始 int lieHei = 0;//是否有黑点 int lieBai = 0;//是否有白点 int nX = 0;//第n个验证码,X方向看 int[,] PicBlackPixelY = new int[4, height];//4个验证码黑点像素点集合Y坐标 StringBuilder sb = new StringBuilder();//图片全部黑点坐标临时存储 for (int X = 0; X < width; X++) //x坐标 { for (int Y = 1; Y < height - 1; Y++) //y坐标 { //点(X,Y)的颜色 if (Y >= 1 && Y <= height - 2) { string color = ColorTranslator.ToHtml(bitmap.GetPixel(X, Y)); if (Con42(color.Substring(1, 1),16) >= 0 && Con42(color.Substring(1, 1),16) < 7) { lieHei = 1;//存在黑点 try { PicBlackPixelY[nX, Y] = Y; } catch { } } else { lieBai = 1;//存在白点 } } } if (lieBai == 1 && lieHei == 1 && isStart == 0)//黑白相间 { try { xArray[nX, 0] = X; } catch { } isStart = 1; } if (lieBai == 1 && lieHei == 0 && isStart == 1)//全白 { try { xArray[nX, 1] = X; } catch { } isStart = 0;//结束 nX++; } lieHei = 0; lieBai = 0; } //算出5个验证码y轴方向 最大最小 黑点坐标 for (int i = 0; i < 5; i++) { int minY = height; int maxY = 0; for (int j = 0; j < height; j++) { if (PicBlackPixelY[i, j] < minY && PicBlackPixelY[i, j] > 0) { minY = PicBlackPixelY[i, j]; } if (PicBlackPixelY[i, j] > maxY) { maxY = PicBlackPixelY[i, j]; } } yArray[i, 0] = minY - 1; yArray[i, 1] = maxY + 1; } for (int i = 0; i < 4; i++) { width = xArray[i, 1] - xArray[i, 0]; height = yArray[i, 1] - yArray[i, 0]; for (int offsetX = 0; offsetX < width; offsetX++) //x坐标 { for (int offsetY = 0; offsetY < height; offsetY++) //y坐标 { //获得验证码图片点的颜色 string color = ColorTranslator.ToHtml(bitmap.GetPixel(xArray[i, 0] + offsetX, yArray[i, 0] + offsetY)); 8 if (Con42(color.Substring(1, 1),16) >= 0 && Con42(color.Substring(1, 1),16) < 8) { sb.Append(offsetX.ToString()).Append(offsetY.ToString()).Append(","); } } } sb.Remove(sb.Length - 1, 1); sb.AppendLine("|"); } bitmap.Dispose(); //得到验证码 int[] Key = ComparePic(sb); return Key; } /// <summary> /// 比较图片相似度已确定验证码对应数字 /// </summary> /// <param name="sb"></param> /// <returns></returns> private int[] ComparePic(StringBuilder sb) { //特征图片像素点集合:数字0-9像素点集合,做对比用 ArrayList arr = new ArrayList(); arr.Add(new int[] { 03, 04, 05, 06, 07, 08, 09, 12, 13, 14, 15, 16, 17, 19, 110, 21, 22, 23, 24, 25, 26, 27, 28, 29, 210, 211, 31, 32, 33, 39, 310, 311, 41, 42, 45, 411, 51, 53, 59, 510, 511, 62, 63, 64, 66, 67, 68, 610, 611, 72, 73, 74, 75, 76, 77, 78, 79, 710, 83, 84, 85, 86, 87, 88, 89 }); arr.Add(new int[] { 04, 05, 13, 14, 15, 22, 23, 24, 31, 32, 33, 34, 35, 36, 37, 38, 39, 310, 311, 41, 42, 43, 44, 45, 46, 47, 48, 49, 410, 411, 51, 52, 53, 54, 55, 57, 58, 59, 510, 511 }); arr.Add(new int[] { 04, 010, 011, 13, 14, 19, 110, 111, 21, 22, 23, 24, 28, 29, 210, 211, 31, 32, 33, 37, 38, 39, 310, 311, 41, 42, 46, 47, 48, 49, 410, 411, 51, 53, 55, 56, 57, 58, 510, 511, 61, 62, 63, 64, 65, 66, 67, 610, 611, 71, 72, 73, 74, 75, 76, 710, 711, 82, 83, 84, 85, 810, 811 }); arr.Add(new int[] { 02, 03, 09, 010, 11, 12, 13, 18, 19, 110, 111, 21, 22, 23, 29, 210, 211, 31, 32, 35, 36, 310, 311, 41, 42, 45, 46, 410, 411, 51, 52, 53, 54, 55, 56, 57, 59, 510, 511, 61, 62, 63, 64, 65, 66, 67, 68, 69, 610, 611, 72, 73, 74, 76, 77, 78, 79, 710, 87, 88, 89 }); arr.Add(new int[] { 08, 09, 16, 17, 18, 19, 25, 26, 28, 29, 34, 35, 36, 37, 38, 39, 43, 44, 45, 48, 49, 52, 53, 54, 58, 59, 61, 62, 63, 64, 65, 66, 67, 68, 610, 611, 71, 73, 74, 75, 76, 77, 78, 79, 710, 711, 81, 82, 83, 84, 85, 86, 87, 88, 89, 811, 98, 99 }); arr.Add(new int[] { 04, 05, 09, 11, 12, 13, 14, 15, 16, 19, 110, 21, 22, 23, 24, 25, 26, 29, 210, 32, 33, 34, 35, 39, 310, 311, 41, 42, 44, 45, 410, 411, 51, 52, 54, 55, 59, 510, 511, 61, 62, 64, 65, 66, 67, 68, 69, 610, 611, 71, 72, 75, 76, 77, 78, 79, 710, 81, 82, 85, 86, 87, 88, 89 }); arr.Add(new int[] { 04, 05, 06, 07, 08, 09, 12, 13, 14, 15, 16, 17, 18, 19, 110, 21, 22, 23, 25, 26, 27, 28, 29, 210, 31, 32, 33, 36, 37, 39, 310, 311, 41, 42, 45, 46, 410, 411, 51, 52, 55, 510, 511, 61, 62, 63, 65, 66, 67, 68, 69, 610, 611, 72, 73, 76, 77, 78, 79, 710, 83, 86, 87, 88, 89, 810 }); arr.Add(new int[] { 01, 02, 11, 12, 21, 22, 28, 29, 210, 211, 31, 32, 37, 38, 39, 310, 41, 42, 44, 45, 46, 47, 48, 49, 410, 411, 51, 53, 54, 55, 56, 57, 58, 61, 62, 63, 64, 65, 71, 72, 73, 81, 82 }); arr.Add(new int[] { 02, 03, 04, 07, 08, 09, 010, 12, 13, 14, 16, 17, 18, 19, 110, 111, 21, 22, 23, 24, 25, 26, 27, 28, 29, 210, 211, 31, 32, 33, 35, 36, 37, 39, 310, 311, 41, 42, 45, 46, 410, 411, 51, 52, 55, 56, 57, 59, 510, 511, 61, 62, 63, 64, 65, 66, 67, 68, 69, 610, 611, 72, 74, 75, 76, 77, 78, 710, 82, 83, 84, 88, 89 }); arr.Add(new int[] { 03, 05, 09, 12, 13, 14, 15, 16, 17, 19, 110, 21, 22, 23, 24, 25, 26, 29, 210, 211, 31, 32, 33, 35, 36, 37, 39, 310, 311, 41, 42, 46, 47, 410, 411, 51, 52, 56, 59, 510, 511, 61, 63, 64, 65, 66, 67, 68, 69, 610, 72, 73, 74, 75, 76, 77, 78, 79, 710, 83, 84, 85, 86, 87, 88, 89 }); int[] Key = new int[4]; string[] picPixel = sb.ToString().Split('|');//各验证码点集合 //对比相似程度 for (int i = 0; i < 4; i++) { string[] p = picPixel[i].Split(','); for (int j = 0; j < 10; j++) { int[] B = (int[])(arr[j]); try { //选出当前验证码跟特征图片相同的点 var q = from a in p join b in B on Convert.ToInt32(a) equals b select b; //相似程度 = 相似像素点数/当前验证数字像素数 double xs = (double)q.Count<int>() / (double)p.Length; if (xs > 0.9)//90%相似,表明该图片就是该数字了 { Key[i] = j; break; } } catch { } } } return Key; } /// <summary> /// 放大缩小图片尺寸 /// </summary> /// <param name="picPath"></param> /// <param name="reSizePicPath"></param> /// <param name="iSize"></param> /// <param name="format"></param> public void PicSized(string picPath, string reSizePicPath, int iSize, ImageFormat format) { Bitmap originBmp = new Bitmap(picPath); int w = originBmp.Width * iSize; int h = originBmp.Height * iSize; Bitmap resizedBmp = new Bitmap(w, h); Graphics g = Graphics.FromImage(resizedBmp); //设置高质量插值法 g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; //设置高质量,低速度呈现平滑程度 g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; //消除锯齿 g.SmoothingMode = SmoothingMode.AntiAlias; g.DrawImage(originBmp, new Rectangle(0, 0, w, h), new Rectangle(0, 0, originBmp.Width, originBmp.Height), GraphicsUnit.Pixel); resizedBmp.Save(reSizePicPath, format); g.Dispose(); resizedBmp.Dispose(); originBmp.Dispose(); } /// <summary> /// 彩色图片转化为黑白 /// </summary> /// <param name="source"></param> /// <returns></returns> public Bitmap ConvertToGrayscale(Bitmap bitmap) { Bitmap bm = new Bitmap(bitmap.Width, bitmap.Height); for (int y = 0; y < bm.Height; y++) { for (int x = 0; x < bm.Width; x++) { Color c = bitmap.GetPixel(x, y); int rgb = (int)(c.R * 0.3 + c.G * 0.59 + c.B * 0.11); bm.SetPixel(x, y, Color.FromArgb(rgb, rgb, rgb)); } } return bm; } #endregion

    看来还不少啊。很麻烦吧。其实让我欣慰的是C#真强大。应该比我想象的要强大的多多!

    本文参考:

    http://www.docin.com/p1-179876212.html


    最新回复(0)