验证码常用函数备忘
Posted 冰封一夏
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了验证码常用函数备忘相关的知识,希望对你有一定的参考价值。
颜色聚类
1 public static class KmeansColor 2 { 3 /* 4 * 聚类函数主体。 5 * 针对一维 double 数组。指定聚类数目 k。 6 * 将数据聚成 k 类。 7 */ 8 public static Color[][] cluster(Color[] p, int k) 9 { 10 int intRunCount = 0; 11 start: 12 intRunCount++; 13 // 存放聚类旧的聚类中心 14 Color[] c = new Color[k]; 15 // 存放新计算的聚类中心 16 Color[] nc = new Color[k]; 17 // 存放放回结果 18 Color[][] g; 19 // 初始化聚类中心 20 // 经典方法是随机选取 k 个 21 // 本例中采用前 k 个作为聚类中心 22 // 聚类中心的选取不影响最终结果 23 Random r = new Random(); 24 25 int intValue = -16777216 / k; 26 for (int i = 0; i < k; i++) 27 { 28 c[i] = Color.FromArgb(r.Next(1, 255), r.Next(1, 255), r.Next(1, 255)); 29 } 30 // 循环聚类,更新聚类中心 31 // 到聚类中心不变为止 32 while (true) 33 { 34 // 根据聚类中心将元素分类 35 g = group(p, c); 36 // 计算分类后的聚类中心 37 for (int i = 0; i < g.Length; i++) 38 { 39 nc[i] = center(g[i]); 40 } 41 // 如果聚类中心不同 42 if (!equal(nc, c)) 43 { 44 // 为下一次聚类准备 45 c = nc; 46 nc = new Color[k]; 47 } 48 else // 聚类结束 49 { 50 foreach (var item in g) 51 { 52 if (intRunCount < 10000 && item.Length <= 50) 53 { 54 goto start; 55 } 56 } 57 break; 58 } 59 } 60 // 返回聚类结果 61 return g; 62 } 63 /* 64 * 聚类中心函数 65 * 简单的一维聚类返回其算数平均值 66 * 可扩展 67 */ 68 public static Color center(Color[] p) 69 { 70 if (p.Length <= 0) 71 { 72 Random r = new Random(); 73 return Color.FromArgb(r.Next(1, 255), r.Next(1, 255), r.Next(1, 255)); 74 } 75 int intSumR = 0, intSumG = 0, intSumB = 0; 76 foreach (var item in p) 77 { 78 intSumR += item.R; 79 intSumG += item.G; 80 intSumB += item.B; 81 } 82 int intLength = p.Length; 83 return Color.FromArgb(intSumR / intLength, intSumG / intLength, intSumB / intLength); 84 } 85 /* 86 * 给定 double 型数组 p 和聚类中心 c。 87 * 根据 c 将 p 中元素聚类。返回二维数组。 88 * 存放各组元素。 89 */ 90 public static Color[][] group(Color[] p, Color[] c) 91 { 92 // 中间变量,用来分组标记 93 int[] gi = new int[p.Length]; 94 // 考察每一个元素 pi 同聚类中心 cj 的距离 95 // pi 与 cj 的距离最小则归为 j 类 96 for (int i = 0; i < p.Length; i++) 97 { 98 // 存放距离 99 double[] d = new double[c.Length]; 100 // 计算到每个聚类中心的距离 101 for (int j = 0; j < c.Length; j++) 102 { 103 d[j] = distance(p[i], c[j]); 104 } 105 // 找出最小距离 106 int ci = min(d); 107 // 标记属于哪一组 108 gi[i] = ci; 109 } 110 // 存放分组结果 111 Color[][] g = new Color[c.Length][]; 112 // 遍历每个聚类中心,分组 113 for (int i = 0; i < c.Length; i++) 114 { 115 // 中间变量,记录聚类后每一组的大小 116 int s = 0; 117 // 计算每一组的长度 118 for (int j = 0; j < gi.Length; j++) 119 if (gi[j] == i) 120 s++; 121 // 存储每一组的成员 122 g[i] = new Color[s]; 123 s = 0; 124 // 根据分组标记将各元素归位 125 for (int j = 0; j < gi.Length; j++) 126 if (gi[j] == i) 127 { 128 g[i][s] = p[j]; 129 s++; 130 } 131 } 132 // 返回分组结果 133 return g; 134 } 135 136 /* 137 * 计算两个点之间的距离, 这里采用最简单得一维欧氏距离, 可扩展。 138 */ 139 public static double distance(Color x, Color y) 140 { 141 142 return Math.Sqrt(Math.Pow(x.R - y.R, 2) + Math.Pow(x.G - y.G, 2) + Math.Pow(x.B - y.B, 2)); 143 // return Math.Abs(x.R - y.R) + Math.Abs(x.G - y.G) + Math.Abs(x.B - y.B); 144 } 145 146 /* 147 * 返回给定 double 数组各元素之和。 148 */ 149 public static double sum(double[] p) 150 { 151 double sum = 0.0; 152 for (int i = 0; i < p.Length; i++) 153 sum += p[i]; 154 return sum; 155 } 156 157 /* 158 * 给定 double 类型数组,返回最小值得下标。 159 */ 160 public static int min(double[] p) 161 { 162 int i = 0; 163 double m = p[0]; 164 for (int j = 1; j < p.Length; j++) 165 { 166 if (p[j] < m) 167 { 168 i = j; 169 m = p[j]; 170 } 171 } 172 return i; 173 } 174 175 /* 176 * 判断两个 double 数组是否相等。 长度一样且对应位置值相同返回真。 177 */ 178 public static bool equal(Color[] a, Color[] b) 179 { 180 if (a.Length != b.Length) 181 return false; 182 else 183 { 184 for (int i = 0; i < a.Length; i++) 185 { 186 if (a[i].Name != b[i].Name) 187 return false; 188 } 189 } 190 return true; 191 } 192 }
常用函数
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Drawing; 6 using AForge.Imaging.Filters; 7 using AForge.Imaging; 8 using AForge.Math.Geometry; 9 using System.Drawing.Imaging; 10 using AForge; 11 using System.IO; 12 using System.Text.RegularExpressions; 13 using AForge.Math; 14 15 namespace RecogniseCode 16 { 17 /* 18 * 配置文件描述: 19 * 0:去边框 1:颜色去除;2:灰度;3:二值化;4:去噪;5:标记;6:投影检测 20 * ----------------------- 21 * 01:边框宽度 上,右,下,左 22 * ----------------------- 23 * 11:目标颜色,|分割,12:阈值,13:替换颜色 24 * ----------------------- 25 * 21:灰度参数 26 * ----------------------- 27 * 31:二值化参数 28 * ----------------------- 29 * 41:去噪参数 30 * ----------------------- 31 * 51:标记最小大小 32 * 52:是否检查宽度合并 33 * 53:检查宽度合并最大宽度 34 * 54:是否左右旋转以找到最小宽度图片 35 * ----------------------- 36 * 61:是否谷底检查 37 * 62:谷底检查最大高度 38 * 63:是否超宽检查 39 * 64:超宽检查最大宽度 40 */ 41 public class Code2Text 42 { 43 private CodeType m_codeType; 44 private string m_strModePath; 45 private XMLSourceHelp m_xml; 46 /// <summary> 47 /// 功能描述:构造函数 48 /// 作 者:huangzh 49 /// 创建日期:2016-09-01 15:21:27 50 /// 任务编号: 51 /// </summary> 52 /// <param name="codeType">验证码类型</param> 53 /// <param name="strModePath">验证码识别模板文件夹路径</param> 54 public Code2Text(CodeType codeType, string strModePath) 55 { 56 m_codeType = codeType; 57 m_strModePath = strModePath; 58 if (!Directory.Exists(strModePath)) 59 { 60 throw new Exception("验证码识别模板文件夹路径不存在"); 61 } 62 string strConfigPath = Path.Combine(m_strModePath, "config.xml"); 63 if (!File.Exists(strConfigPath)) 64 throw new Exception("识别模板配置文件不存在"); 65 m_xml = new XMLSourceHelp(strConfigPath); 66 } 67 68 /// <summary> 69 /// 功能描述:识别验证码结果 70 /// 作 者:huangzh 71 /// 创建日期:2016-09-01 16:25:45 72 /// 任务编号: 73 /// </summary> 74 /// <param name="bit">bit</param> 75 /// <returns>返回值</returns> 76 public string GetCodeText(Bitmap bit) 77 { 78 switch (m_codeType) 79 { 80 case CodeType.Tianjin: 81 return GetTianJin(bit); 82 case CodeType.LiaoNing: 83 return GetLiaoNing(bit); 84 case CodeType.JiangSu: 85 return GetJiangSu(bit); 86 case CodeType.JiangXi: 87 return GetJiangXi(bit); 88 case CodeType.ChongQing: 89 return GetChongQing(bit); 90 case CodeType.NingXia: 91 return GetNingXia(bit); 92 case CodeType.XinJiang: 93 return GetXinJiang(bit); 94 case CodeType.TianYanCha: 95 return GetTianYanCha(bit); 96 case CodeType.BeiJing: 97 return GetBeiJing(bit); 98 case CodeType.QingHai: 99 return GetQingHai(bit); 100 case CodeType.ShanXi: 101 return GetShanXi(bit); 102 case CodeType.HeiLongJiang: 103 return GetHeiLongJiang(bit); 104 default: return ""; 105 } 106 } 107 108 #region 具体验证码识别 109 /// <summary> 110 /// 功能描述:获取天津验证码结果 111 /// 作 者:huangzh 112 /// 创建日期:2016-09-01 16:26:00 113 /// 任务编号: 114 /// </summary> 115 /// <param name="bitImage">bitImage</param> 116 /// <returns>识别结果,如果为空,则为识别失败</returns> 117 private string GetTianJin(Bitmap bitImage) 118 { 119 //颜色去除 120 bitImage = ClearColor(bitImage); 121 122 //灰度 123 bitImage = HuiDu(bitImage); 124 125 //二值化 126 bitImage = ErZhi(bitImage); 127 128 //反转 129 bitImage = ColorFanZhuan(bitImage); 130 131 //去噪 132 bitImage = QuZao(bitImage); 133 134 //标记识别 135 List<string> lstChar = GetImageChar(GetLianTongImage(bitImage)); 136 string strNum1 = string.Empty; 137 string strYun = string.Empty; 138 string strNum2 = string.Empty; 139 foreach (string strItem in lstChar) 140 { 141 if (Regex.IsMatch(strItem, @"\\d+")) 142 { 143 if (string.IsNullOrEmpty(strYun)) 144 { 145 strNum1 += strItem; 146 } 147 else 148 { 149 strNum2 += strItem; 150 } 151 } 152 else if (Regex.IsMatch(strItem, @"\\+|\\-|\\#")) 153 { 154 if (string.IsNullOrEmpty(strYun)) 155 { 156 strYun = strItem; 157 } 158 } 159 else if (Regex.IsMatch(strItem, @"\\=")) 160 { 161 162 } 163 } 164 165 if (!string.IsNullOrEmpty(strNum1) && !string.IsNullOrEmpty(strYun) && !string.IsNullOrEmpty(strNum2)) 166 { 167 int intNum1 = int.Parse(strNum1); 168 int intNum2 = int.Parse(strNum2); 169 switch (strYun) 170 { 171 case "+": return (intNum1 + intNum2).ToString(); 172 case "-": return (intNum1 - intNum2).ToString(); 173 case "#": return (intNum1 * intNum2).ToString(); 174 default: return string.Empty; 175 } 176 } 177 return string.Empty; 178 以上是关于验证码常用函数备忘的主要内容,如果未能解决你的问题,请参考以下文章