验证码常用函数备忘

颜色聚类

  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     }
View Code

常用函数

   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         }
 179 
 180         /// <summary>
 181         /// 功能描述:获取辽宁验证码结果
 182         /// 作  者:huangzh
 183         /// 创建日期:2016-09-02 09:30:56
 184         /// 任务编号:
 185         /// </summary>
 186         /// <param name="bitImage">bitImage</param>
 187         /// <returns>返回值</returns>
 188         private string GetLiaoNing(Bitmap bitImage)
 189         {
 190             //灰度  
 191             bitImage = HuiDu(bitImage);
 192 
 193             //二值化
 194             bitImage = ErZhi(bitImage);
 195 
 196             //去噪           
 197             bitImage = QuZao(bitImage);
 198 
 199             //标记识别            
 200             List<string> lstChar = GetImageChar(GetLianTongImage(bitImage));
 201 
 202             return string.Join("", lstChar);
 203         }
 204 
 205         /// <summary>
 206         /// 功能描述:获取江苏验证码结果
 207         /// 作  者:huangzh
 208         /// 创建日期:2016-09-02 09:35:09
 209         /// 任务编号:
 210         /// </summary>
 211         /// <param name="bitImage">bitImage</param>
 212         /// <returns>返回值</returns>
 213         private string GetJiangSu(Bitmap bitImage)
 214         {
 215             //灰度  
 216             bitImage = HuiDu(bitImage);
 217 
 218             //二值化
 219             bitImage = ErZhi(bitImage);
 220 
 221             //反转
 222             bitImage = ColorFanZhuan(bitImage);
 223 
 224             //去噪           
 225             bitImage = QuZao(bitImage);
 226 
 227             //毛边
 228             bitImage = ClearMaoBian(bitImage);
 229 
 230             //反转
 231             bitImage = ColorFanZhuan(bitImage);
 232 
 233             //毛边
 234             bitImage = ClearMaoBian(bitImage);
 235 
 236             //反转
 237             bitImage = ColorFanZhuan(bitImage);
 238 
 239             //标记识别            
 240             List<string> lstChar = GetImageChar(GetLianTongImage(bitImage));
 241 
 242             return string.Join("", lstChar);
 243         }
 244 
 245         /// <summary>
 246         /// 功能描述:获取江西验证码结果
 247         /// 作  者:huangzh
 248         /// 创建日期:2016-09-02 10:18:13
 249         /// 任务编号:
 250         /// </summary>
 251         /// <param name="bitImage">bitImage</param>
 252         /// <returns>返回值</returns>
 253         private string GetJiangXi(Bitmap bitImage)
 254         {
 255             //灰度  
 256             bitImage = HuiDu(bitImage);
 257 
 258             //二值化
 259             bitImage = ErZhi(bitImage);
 260 
 261             //反转
 262             bitImage = ColorFanZhuan(bitImage);
 263 
 264             //去噪           
 265             bitImage = QuZao(bitImage);
 266 
 267             //标记识别            
 268             List<string> lstChar = GetImageChar(GetLianTongImage(bitImage));
 269             string strNum1 = string.Empty;
 270             string strYun = string.Empty;
 271             string strNum2 = string.Empty;
 272             foreach (string strItem in lstChar)
 273             {
 274                 if (Regex.IsMatch(strItem, @"d+"))
 275                 {
 276                     if (string.IsNullOrEmpty(strYun))
 277                     {
 278                         strNum1 += strItem;
 279                     }
 280                     else
 281                     {
 282                         strNum2 += strItem;
 283                     }
 284                 }
 285                 else if (Regex.IsMatch(strItem, @"+|-|#"))
 286                 {
 287                     if (string.IsNullOrEmpty(strYun))
 288                     {
 289                         strYun = strItem;
 290                     }
 291                 }
 292                 else if (Regex.IsMatch(strItem, @"="))
 293                 {
 294 
 295                 }
 296             }
 297 
 298             if (!string.IsNullOrEmpty(strNum1) && !string.IsNullOrEmpty(strYun) && !string.IsNullOrEmpty(strNum2))
 299             {
 300                 int intNum1 = int.Parse(strNum1);
 301                 int intNum2 = int.Parse(strNum2);
 302                 switch (strYun)
 303                 {
 304                     case "+": return (intNum1 + intNum2).ToString();
 305                     case "-": return (intNum1 - intNum2).ToString();
 306                     case "#": return (intNum1 * intNum2).ToString();
 307                     default: return string.Empty;
 308                 }
 309             }
 310             return string.Empty;
 311         }
 312 
 313         /// <summary>
 314         /// 功能描述:获取重庆验证码结果
 315         /// 作  者:huangzh
 316         /// 创建日期:2016-09-02 10:30:53
 317         /// 任务编号:
 318         /// </summary>
 319         /// <param name="bitImage">bitImage</param>
 320         /// <returns>返回值</returns>
 321         private string GetChongQing(Bitmap bitImage)
 322         {
 323             //灰度  
 324             bitImage = HuiDu(bitImage);
 325 
 326             //二值化
 327             bitImage = ErZhi(bitImage);
 328 
 329             //反转
 330             bitImage = ColorFanZhuan(bitImage);
 331 
 332             //去噪           
 333             bitImage = QuZao(bitImage);
 334 
 335             //毛边
 336             bitImage = ClearMaoBian(bitImage);
 337 
 338             //标记识别            
 339             List<string> lstChar = GetImageChar(GetLianTongImage(bitImage));
 340             string strNum1 = string.Empty;
 341             string strYun = string.Empty;
 342             string strNum2 = string.Empty;
 343             foreach (string strItem in lstChar)
 344             {
 345                 if (Regex.IsMatch(strItem, @"d+"))
 346                 {
 347                     if (string.IsNullOrEmpty(strYun))
 348                     {
 349                         strNum1 += strItem;
 350                     }
 351                     else
 352                     {
 353                         strNum2 += strItem;
 354                     }
 355                 }
 356                 else if (Regex.IsMatch(strItem, @"+|-|#"))
 357                 {
 358                     if (string.IsNullOrEmpty(strYun))
 359                     {
 360                         strYun = strItem;
 361                     }
 362                 }
 363                 else if (Regex.IsMatch(strItem, @"="))
 364                 {
 365 
 366                 }
 367             }
 368 
 369             if (!string.IsNullOrEmpty(strNum1) && !string.IsNullOrEmpty(strYun) && !string.IsNullOrEmpty(strNum2))
 370             {
 371                 int intNum1 = int.Parse(strNum1);
 372                 int intNum2 = int.Parse(strNum2);
 373                 switch (strYun)
 374                 {
 375                     case "+": return (intNum1 + intNum2).ToString();
 376                     case "-": return (intNum1 - intNum2).ToString();
 377                     case "#": return (intNum1 * intNum2).ToString();
 378                     default: return string.Empty;
 379                 }
 380             }
 381             return string.Empty;
 382         }
 383 
 384         /// <summary>
 385         /// 功能描述:获取宁夏验证码结果
 386         /// 作  者:huangzh
 387         /// 创建日期:2016-09-02 10:41:18
 388         /// 任务编号:
 389         /// </summary>
 390         /// <param name="bitImage">bitImage</param>
 391         /// <returns>返回值</returns>
 392         private string GetNingXia(Bitmap bitImage)
 393         {
 394             //灰度  
 395             bitImage = HuiDu(bitImage);
 396 
 397             //二值化
 398             bitImage = ErZhi(bitImage);
 399 
 400             //反转
 401             bitImage = ColorFanZhuan(bitImage);
 402 
 403             //去噪           
 404             bitImage = QuZao(bitImage);
 405 
 406             //标记识别            
 407             List<string> lstChar = GetImageChar(GetLianTongImage(bitImage));
 408             string strNum1 = string.Empty;
 409             string strYun = string.Empty;
 410             string strNum2 = string.Empty;
 411             foreach (string strItem in lstChar)
 412             {
 413                 if (Regex.IsMatch(strItem, @"d+"))
 414                 {
 415                     if (string.IsNullOrEmpty(strYun))
 416                     {
 417                         strNum1 += strItem;
 418                     }
 419                     else
 420                     {
 421                         strNum2 += strItem;
 422                     }
 423                 }
 424                 else if (Regex.IsMatch(strItem, @"+|-|#"))
 425                 {
 426                     if (string.IsNullOrEmpty(strYun))
 427                     {
 428                         strYun = strItem;
 429                     }
 430                 }
 431                 else if (Regex.IsMatch(strItem, @"="))
 432                 {
 433 
 434                 }
 435             }
 436 
 437             if (!string.IsNullOrEmpty(strNum1) && !string.IsNullOrEmpty(strYun) && !string.IsNullOrEmpty(strNum2))
 438             {
 439                 int intNum1 = int.Parse(strNum1);
 440                 int intNum2 = int.Parse(strNum2);
 441                 switch (strYun)
 442                 {
 443                     case "+": return (intNum1 + intNum2).ToString();
 444                     case "-": return (intNum1 - intNum2).ToString();
 445                     case "#": return (intNum1 * intNum2).ToString();
 446                     default: return string.Empty;
 447                 }
 448             }
 449             return string.Empty;
 450         }
 451 
 452         /// <summary>
 453         /// 功能描述:获取新疆验证码结果
 454         /// 作  者:huangzh
 455         /// 创建日期:2016-09-02 10:46:09
 456         /// 任务编号:
 457         /// </summary>
 458         /// <param name="bitImage">bitImage</param>
 459         /// <returns>返回值</returns>
 460         private string GetXinJiang(Bitmap bitImage)
 461         {
 462             //灰度  
 463             bitImage = HuiDu(bitImage);
 464 
 465             //二值化
 466             bitImage = ErZhi(bitImage);
 467 
 468             //反转
 469             bitImage = ColorFanZhuan(bitImage);
 470 
 471             //去噪           
 472             bitImage = QuZao(bitImage);
 473 
 474             List<Bitmap> lstBits = GetLianTongImage(bitImage);
 475 
 476 
 477             //int intWidth = int.Parse(m_xml.ConvertIdToName("maxWidth", "-1"));
 478             //for (int i = 0; i < lstBits.Count; i++)
 479             //{
 480             //    Bitmap bit = lstBits[i];
 481             //    int intMinWidth = GetMinBitmap(bit).Width;
 482             //    if (intMinWidth >= intWidth + 2)
 483             //    {
 484             //        Bitmap bit1 = bit.Clone(new Rectangle(0, 0, intWidth, bit.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
 485             //        Bitmap bit2 = bit.Clone(new Rectangle(intWidth, 0, bit.Width - intWidth, bit.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
 486             //        lstBits.RemoveAt(i);
 487             //        lstBits.Insert(i, bit2);
 488             //        lstBits.Insert(i, bit1);
 489             //        break;
 490             //    }
 491             //}
 492 
 493             //标记识别            
 494             List<string> lstChar = GetImageChar(lstBits);
 495             string strNum1 = string.Empty;
 496             string strYun = string.Empty;
 497             string strNum2 = string.Empty;
 498             foreach (string strItem in lstChar)
 499             {
 500                 if (Regex.IsMatch(strItem, @"d+"))
 501                 {
 502                     if (string.IsNullOrEmpty(strYun))
 503                     {
 504                         strNum1 += strItem;
 505                     }
 506                     else
 507                     {
 508                         strNum2 += strItem;
 509                     }
 510                 }
 511                 else if (Regex.IsMatch(strItem, @"+|-|#"))
 512                 {
 513                     if (string.IsNullOrEmpty(strYun))
 514                     {
 515                         strYun = strItem;
 516                     }
 517                 }
 518                 else if (Regex.IsMatch(strItem, @"="))
 519                 {
 520                     break;
 521                 }
 522             }
 523 
 524             if (!string.IsNullOrEmpty(strNum1) && !string.IsNullOrEmpty(strYun) && !string.IsNullOrEmpty(strNum2))
 525             {
 526                 int intNum1 = int.Parse(strNum1);
 527                 int intNum2 = int.Parse(strNum2);
 528                 switch (strYun)
 529                 {
 530                     case "+": return (intNum1 + intNum2).ToString();
 531                     case "-": return (intNum1 - intNum2).ToString();
 532                     case "#": return (intNum1 * intNum2).ToString();
 533                     default: return string.Empty;
 534                 }
 535             }
 536             return string.Empty;
 537         }
 538 
 539 
 540 
 541         /// <summary>
 542         /// 功能描述:获取天眼查验证码结果
 543         /// 作  者:huangzh
 544         /// 创建日期:2016-09-06 12:28:32
 545         /// 任务编号:
 546         /// </summary>
 547         /// <param name="bitImage">bitImage</param>
 548         /// <returns>返回值</returns>
 549         private string GetTianYanCha(Bitmap bitImage)
 550         {
 551             bitImage = ClearBroder(bitImage);
 552             bitImage = HuiDu(bitImage);
 553             bitImage = ErZhi(bitImage);
 554             bitImage = ColorFanZhuan(bitImage);
 555             bitImage = QuZao(bitImage);
 556             List<Bitmap> lstImages = GetLianTongImage(bitImage);
 557             List<string> lstChar = GetImageChar(lstImages);
 558             return string.Join("", lstChar);
 559         }
 560 
 561         /// <summary>
 562         /// 功能描述:获取北京验证码结果
 563         /// 作  者:huangzh
 564         /// 创建日期:2016-09-07 16:14:42
 565         /// 任务编号:
 566         /// </summary>
 567         /// <param name="bitImage">bitImage</param>
 568         /// <returns>返回值</returns>
 569         private string GetBeiJing(Bitmap bitImage)
 570         {
 571             bitImage = ClearColor(bitImage);
 572 
 573             //灰度  
 574             bitImage = HuiDu(bitImage);
 575 
 576             //二值化
 577             bitImage = ErZhi(bitImage);
 578 
 579             //反转
 580             bitImage = ColorFanZhuan(bitImage);
 581 
 582             //去噪           
 583             bitImage = QuZao(bitImage);
 584 
 585             //标记识别            
 586             List<string> lstChar = GetImageChar(GetLianTongImage(bitImage));
 587             string strNum1 = string.Empty;
 588             string strYun = string.Empty;
 589             string strNum2 = string.Empty;
 590             foreach (string strItem in lstChar)
 591             {
 592                 if (strItem == "$")
 593                     continue;
 594                 if (Regex.IsMatch(strItem, @"d+"))
 595                 {
 596                     if (string.IsNullOrEmpty(strYun))
 597                     {
 598                         if (string.IsNullOrEmpty(strNum1))
 599                             strNum1 = strItem;
 600                         else if (strItem != "1")
 601                             strNum1 = strItem;
 602                     }
 603                     else
 604                     {
 605                         if (string.IsNullOrEmpty(strNum2))
 606                         {
 607                             strNum2 = strItem;
 608                             if (strItem != "1")
 609                                 break;
 610                         }
 611                         else if (strItem != "1")
 612                             strNum2 = strItem;
 613                     }
 614                 }
 615                 else if (Regex.IsMatch(strItem, @"+|-|#"))
 616                 {
 617                     if (string.IsNullOrEmpty(strYun))
 618                     {
 619                         strYun = strItem;
 620                     }
 621                 }
 622                 else if (Regex.IsMatch(strItem, @"="))
 623                 {
 624                     break;
 625                 }
 626             }
 627 
 628             if (!string.IsNullOrEmpty(strNum1) && !string.IsNullOrEmpty(strYun) && !string.IsNullOrEmpty(strNum2))
 629             {
 630                 int intNum1 = int.Parse(strNum1);
 631                 int intNum2 = int.Parse(strNum2);
 632                 switch (strYun)
 633                 {
 634                     case "+": return (intNum1 + intNum2).ToString();
 635                     case "-": return (intNum1 - intNum2).ToString();
 636                     case "#": return (intNum1 * intNum2).ToString();
 637                     default: return string.Empty;
 638                 }
 639             }
 640             return string.Empty;
 641         }
 642 
 643         /// <summary>
 644         /// 功能描述:获取青海验证码结果
 645         /// 作  者:huangzh
 646         /// 创建日期:2016-09-08 17:20:13
 647         /// 任务编号:
 648         /// </summary>
 649         /// <param name="bitImage">bitImage</param>
 650         /// <returns>返回值</returns>
 651         private string GetQingHai(Bitmap bitImage)
 652         {
 653             Bitmap bitBase = bitImage.Clone(new Rectangle(0, 0, bitImage.Width, bitImage.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
 654             bitImage = ClearColor(bitImage);
 655 
 656             //灰度  
 657             bitImage = HuiDu(bitImage);
 658 
 659             //二值化
 660             bitImage = ErZhi(bitImage);
 661 
 662             //反转
 663             bitImage = ColorFanZhuan(bitImage);
 664 
 665             //去噪           
 666             bitImage = QuZao(bitImage);
 667 
 668             List<Bitmap> lstImages = GetTouYingImages(bitImage, bitBase);
 669             //for (int i = 0; i < lstImages.Count; i++)
 670             //{
 671             //    lstImages[i].Save("d:\" + i + ".jpg");
 672             //}
 673             //标记识别            
 674             List<string> lstChar = GetImageChar(lstImages);
 675             string strNum1 = string.Empty;
 676             string strYun = string.Empty;
 677             string strNum2 = string.Empty;
 678             foreach (string strItem in lstChar)
 679             {
 680                 if (strItem == "$")
 681                     continue;
 682                 if (Regex.IsMatch(strItem, @"d+"))
 683                 {
 684                     if (string.IsNullOrEmpty(strYun))
 685                     {
 686                         strNum1 += strItem;
 687                     }
 688                     else
 689                     {
 690                         strNum2 = strItem;
 691                     }
 692                 }
 693                 else if (Regex.IsMatch(strItem, @"+|-|#|\%"))
 694                 {
 695                     if (string.IsNullOrEmpty(strYun))
 696                     {
 697                         strYun = strItem;
 698                     }
 699                 }
 700                 else if (Regex.IsMatch(strItem, @"="))
 701                 {
 702                     break;
 703                 }
 704             }
 705 
 706             if (!string.IsNullOrEmpty(strNum1) && !string.IsNullOrEmpty(strYun) && !string.IsNullOrEmpty(strNum2))
 707             {
 708                 int intNum1 = int.Parse(strNum1);
 709                 int intNum2 = int.Parse(strNum2);
 710                 switch (strYun)
 711                 {
 712                     case "+": return (intNum1 + intNum2).ToString();
 713                     case "-": return (intNum1 - intNum2).ToString();
 714                     case "#": return (intNum1 * intNum2).ToString();
 715                     case "%": return (intNum1 / intNum2).ToString();
 716                     default: return string.Empty;
 717                 }
 718             }
 719             return string.Empty;
 720         }
 721 
 722         /// <summary>
 723         /// 功能描述:获取山西识别结果
 724         /// 作  者:huangzh
 725         /// 创建日期:2016-09-09 12:14:46
 726         /// 任务编号:
 727         /// </summary>
 728         /// <param name="bitImage">bitImage</param>
 729         /// <returns>返回值</returns>
 730         private string GetShanXi(Bitmap bitImage)
 731         {
 732             Bitmap bitBase = bitImage.Clone(new Rectangle(0, 0, bitImage.Width, bitImage.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
 733             bitImage = ClearColor(bitImage);
 734 
 735             //灰度  
 736             bitImage = HuiDu(bitImage);
 737 
 738             //二值化
 739             bitImage = ErZhi(bitImage);
 740 
 741             //反转
 742             bitImage = ColorFanZhuan(bitImage);
 743 
 744             //去噪           
 745             bitImage = QuZao(bitImage);
 746 
 747             List<Bitmap> lstImages = GetTouYingImages(bitImage, bitBase, 1);
 748             //for (int i = 0; i < lstImages.Count; i++)
 749             //{
 750             //    lstImages[i].Save("d:\" + i + ".jpg");
 751             //}
 752             //标记识别            
 753             List<string> lstChar = GetImageChar(lstImages);
 754             string strNum1 = string.Empty;
 755             string strYun = string.Empty;
 756             string strNum2 = string.Empty;
 757             foreach (string strItem in lstChar)
 758             {
 759                 if (strItem == "$")
 760                     continue;
 761                 if (Regex.IsMatch(strItem, @"d+"))
 762                 {
 763                     if (string.IsNullOrEmpty(strYun))
 764                     {
 765                         strNum1 += strItem;
 766                     }
 767                     else if (string.IsNullOrEmpty(strNum2))
 768                     {
 769                         strNum2 = strItem;
 770                     }
 771                 }
 772                 else if (Regex.IsMatch(strItem, @"+|-|#|\%"))
 773                 {
 774                     if (string.IsNullOrEmpty(strYun))
 775                     {
 776                         strYun = strItem;
 777                     }
 778                 }
 779                 else if (Regex.IsMatch(strItem, @"="))
 780                 {
 781                     break;
 782                 }
 783             }
 784 
 785             if (!string.IsNullOrEmpty(strNum1) && !string.IsNullOrEmpty(strYun) && !string.IsNullOrEmpty(strNum2))
 786             {
 787                 int intNum1 = int.Parse(strNum1);
 788                 int intNum2 = int.Parse(strNum2);
 789                 switch (strYun)
 790                 {
 791                     case "+": return (intNum1 + intNum2).ToString();
 792                     case "-": return (intNum1 - intNum2).ToString();
 793                     case "#": return (intNum1 * intNum2).ToString();
 794                     case "%": return (intNum1 / intNum2).ToString();
 795                     default: return string.Empty;
 796                 }
 797             }
 798             return string.Empty;
 799         }
 800 
 801         /// <summary>
 802         /// 功能描述:获取黑龙江验证码结果
 803         /// 作  者:huangzh
 804         /// 创建日期:2016-09-09 16:46:32
 805         /// 任务编号:
 806         /// </summary>
 807         /// <param name="bitImage">bitImage</param>
 808         /// <returns>返回值</returns>
 809         private string GetHeiLongJiang(Bitmap bitImage)
 810         {
 811             Bitmap bitBase = bitImage.Clone(new Rectangle(0, 0, bitImage.Width, bitImage.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
 812             bitImage = ClearColor(bitImage);
 813 
 814             //灰度  
 815             bitImage = HuiDu(bitImage);
 816 
 817             //二值化
 818             bitImage = ErZhi(bitImage);
 819 
 820             //反转
 821             bitImage = ColorFanZhuan(bitImage);
 822 
 823             //去噪           
 824             bitImage = QuZao(bitImage);
 825 
 826             List<Bitmap> lstImages = GetTouYingImages(bitImage, bitBase, 1);
 827             //for (int i = 0; i < lstImages.Count; i++)
 828             //{
 829             //    lstImages[i].Save("d:\" + i + ".jpg");
 830             //}
 831             //标记识别            
 832             List<string> lstChar = GetImageChar(lstImages);
 833             string strNum1 = string.Empty;
 834             string strYun = string.Empty;
 835             string strNum2 = string.Empty;
 836             foreach (string strItem in lstChar)
 837             {
 838                 if (strItem == "$")
 839                     continue;
 840                 if (Regex.IsMatch(strItem, @"d+"))
 841                 {
 842                     if (string.IsNullOrEmpty(strYun))
 843                     {
 844                         strNum1 += strItem;
 845                     }
 846                     else if (string.IsNullOrEmpty(strNum2))
 847                     {
 848                         strNum2 = strItem;
 849                     }
 850                 }
 851                 else if (Regex.IsMatch(strItem, @"+|-|#|\%"))
 852                 {
 853                     if (string.IsNullOrEmpty(strYun))
 854                     {
 855                         strYun = strItem;
 856                     }
 857                 }
 858                 else if (Regex.IsMatch(strItem, @"="))
 859                 {
 860                     break;
 861                 }
 862             }
 863 
 864             if (!string.IsNullOrEmpty(strNum1) && !string.IsNullOrEmpty(strYun) && !string.IsNullOrEmpty(strNum2))
 865             {
 866                 int intNum1 = int.Parse(strNum1);
 867                 int intNum2 = int.Parse(strNum2);
 868                 switch (strYun)
 869                 {
 870                     case "+": return (intNum1 + intNum2).ToString();
 871                     case "-": return (intNum1 - intNum2).ToString();
 872                     case "#": return (intNum1 * intNum2).ToString();
 873                     case "%": return (intNum1 / intNum2).ToString();
 874                     default: return string.Empty;
 875                 }
 876             }
 877             return string.Empty;
 878         }
 879 
 880         #endregion
 881 
 882         #region 去除边框
 883         private Bitmap ClearBroder(Bitmap bitImage)
 884         {
 885             string[] strs = m_xml.ConvertIdToName("01").Split(',');//上,右,下,左
 886             int[] widths = { int.Parse(strs[0]), int.Parse(strs[1]), int.Parse(strs[2]), int.Parse(strs[3]) };
 887             Bitmap bit = (bitImage as Bitmap).Clone(new Rectangle(0, 0, bitImage.Width, bitImage.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
 888             int intWidth = bit.Width;
 889             int intHeight = bit.Height;
 890             //左右
 891             int inti1 = widths[3];
 892             int inti2 = widths[1];
 893             for (int i = 0; i < intWidth; i++)
 894             {
 895                 if (i < inti1 || i >= intWidth - inti2)
 896                 {
 897                     for (int j = 0; j < intHeight; j++)
 898                     {
 899                         Console.WriteLine(i + "," + j);
 900                         bit.SetPixel(i, j, Color.White);
 901                     }
 902                 }
 903             }
 904 
 905             int intj1 = widths[0];
 906             int intj2 = widths[2];
 907             for (int j = 0; j < intHeight; j++)
 908             {
 909                 if (j < intj1 || j >= intHeight - intj2)
 910                 {
 911                     for (int i = 0; i < intWidth; i++)
 912                     {
 913                         Console.WriteLine(i + "," + j);
 914                         bit.SetPixel(i, j, Color.White);
 915                     }
 916                 }
 917             }
 918             return bit;
 919         }
 920         #endregion
 921 
 922         #region 颜色去除
 923         /// <summary>
 924         /// 功能描述:颜色去除
 925         /// 作  者:huangzh
 926         /// 创建日期:2016-09-01 15:28:08
 927         /// 任务编号:
 928         /// </summary>
 929         /// <param name="bitImage">bitImage</param>
 930         /// <returns>返回值</returns>
 931         private Bitmap ClearColor(Bitmap bitImage)
 932         {
 933             Bitmap bit = bitImage.Clone(new Rectangle(0, 0, bitImage.Width, bitImage.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
 934 
 935             string[] strs = m_xml.ConvertIdToName("11").Split('|');
 936             List<Color> lstCS = new List<Color>();
 937             foreach (var item in strs)
 938             {
 939                 string[] colorStrs = item.Split(',');
 940                 Color c = Color.FromArgb(int.Parse(colorStrs[0]), int.Parse(colorStrs[1]), int.Parse(colorStrs[2]));
 941                 lstCS.Add(c);
 942             }
 943             int intCha = int.Parse(m_xml.ConvertIdToName("12"));
 944             string[] toStrs = m_xml.ConvertIdToName("13").Split(',');
 945             Color cTo = Color.FromArgb(int.Parse(toStrs[0]), int.Parse(toStrs[1]), int.Parse(toStrs[2]));
 946 
 947             int intWidth = bit.Width;
 948             int intHeight = bit.Height;
 949             for (int i = 0; i < intWidth; i++)
 950             {
 951                 for (int j = 0; j < intHeight; j++)
 952                 {
 953                     Color c = bit.GetPixel(i, j);
 954                     foreach (var item in lstCS)
 955                     {
 956                         if (IsClearColor(item, c, intCha))
 957                         {
 958                             bit.SetPixel(i, j, cTo);
 959                             break;
 960                         }
 961                     }
 962 
 963                 }
 964             }
 965 
 966             return bit;
 967         }
 968 
 969         /// <summary>
 970         /// 功能描述:是否需要清除颜色
 971         /// 作  者:huangzh
 972         /// 创建日期:2016-09-01 15:27:28
 973         /// 任务编号:
 974         /// </summary>
 975         /// <param name="c1">c1</param>
 976         /// <param name="c2">c2</param>
 977         /// <param name="intCha">intCha</param>
 978         /// <returns>返回值</returns>
 979         private bool IsClearColor(
 980             Color c1,
 981             Color c2,
 982             int intCha)
 983         {
 984             return Math.Abs(c1.R - c2.R) < intCha && Math.Abs(c1.G - c2.G) < intCha && Math.Abs(c1.B - c2.B) < intCha;
 985         }
 986         #endregion
 987 
 988         #region 灰度
 989         /// <summary>
 990         /// 功能描述:灰度
 991         /// 作  者:huangzh
 992         /// 创建日期:2016-09-01 15:31:00
 993         /// 任务编号:
 994         /// </summary>
 995         /// <param name="bitImage">bitImage</param>
 996         /// <returns>返回值</returns>
 997         private Bitmap HuiDu(
 998             Bitmap bitImage)
 999         {
1000             string[] cs = m_xml.ConvertIdToName("21").Split(',');
1001 
1002             double dbl1 = double.Parse(cs[0]) / 100;
1003             double dbl2 = double.Parse(cs[1]) / 100;
1004             double dbl3 = double.Parse(cs[2]) / 100;
1005             Bitmap bit = bitImage.Clone(new Rectangle(0, 0, bitImage.Width, bitImage.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
1006             Grayscale filter = new Grayscale(dbl1, dbl2, dbl3);
1007             // apply the filter
1008             Bitmap grayImage = filter.Apply(bit);
1009             return grayImage;
1010         }
1011         #endregion
1012 
1013         #region 二值化
1014         /// <summary>
1015         /// 功能描述:二值化
1016         /// 作  者:huangzh
1017         /// 创建日期:2016-09-01 15:33:28
1018         /// 任务编号:
1019         /// </summary>
1020         /// <param name="bitImage">bitImage</param>
1021         /// <returns>返回值</returns>
1022         private Bitmap ErZhi(Bitmap bitImage)
1023         {
1024             int intErZhi = int.Parse(m_xml.ConvertIdToName("31"));
1025             Bitmap bit = bitImage.Clone(new Rectangle(0, 0, bitImage.Width, bitImage.Height), System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
1026             Threshold filter = new Threshold(intErZhi);
1027             // apply the filter
1028             filter.ApplyInPlace(bit);
1029             return bit;
1030         }
1031         #endregion
1032 
1033         #region 颜色反转
1034         /// <summary>
1035         /// 功能描述:颜色反转
1036         /// 作  者:huangzh
1037         /// 创建日期:2016-09-01 15:34:09
1038         /// 任务编号:
1039         /// </summary>
1040         /// <param name="image">image</param>
1041         /// <returns>返回值</returns>
1042         private Bitmap ColorFanZhuan(Bitmap image)
1043         {
1044             image = image.Clone(new Rectangle(0, 0, image.Width, image.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
1045             for (int i = 0; i < image.Width; i++)
1046             {
1047                 for (int j = 0; j < image.Height; j++)
1048                 {
1049                     Color c = image.GetPixel(i, j);
1050                     if (c.Name != "ffffffff")
1051                     {
1052                         image.SetPixel(i, j, Color.White);
1053                     }
1054                     else
1055                     {
1056                         image.SetPixel(i, j, Color.Black);
1057                     }
1058                 }
1059             }
1060             return image;
1061         }
1062         #endregion
1063 
1064         #region 去噪
1065         /// <summary>
1066         /// 功能描述:去噪
1067         /// 作  者:huangzh
1068         /// 创建日期:2016-09-01 15:35:58
1069         /// 任务编号:
1070         /// </summary>
1071         /// <param name="bitImage">bitImage</param>
1072         /// <returns>返回值</returns>
1073         private Bitmap QuZao(Bitmap bitImage)
1074         {
1075             string[] strSizeZao = m_xml.ConvertIdToName("41").Split(',');
1076             Size size = new Size(int.Parse(strSizeZao[0]), int.Parse(strSizeZao[1]));
1077             Bitmap bit = bitImage.Clone(new Rectangle(0, 0, bitImage.Width, bitImage.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
1078             bit = new BlobsFiltering(size.Width, size.Height, bit.Width, bit.Height).Apply(bit);
1079             return bit;
1080         }
1081         #endregion
1082 
1083         #region 去毛边
1084         /// <summary>
1085         /// 功能描述:去毛边
1086         /// 作  者:huangzh
1087         /// 创建日期:2016-09-01 15:36:37
1088         /// 任务编号:
1089         /// </summary>
1090         /// <param name="bitImg">bitImg</param>
1091         /// <returns>返回值</returns>
1092         private static Bitmap ClearMaoBian(Bitmap bitImg)
1093         {
1094             Bitmap bit = bitImg.Clone(new Rectangle(0, 0, bitImg.Width, bitImg.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
1095 
1096             for (int i = 0; i < bit.Width; i++)
1097             {
1098 
1099                 for (int j = 0; j < bit.Height; j++)
1100                 {
1101                     //  Console.WriteLine(i + "," + j);
1102                     Color c = bit.GetPixel(i, j);
1103 
1104                     if (c.Name == "ffffffff")
1105                     {
1106                         //判定上下左右
1107                         int intCount = 0;
1108                         //
1109                         if (j > 0)
1110                         {
1111                             Color c1 = bit.GetPixel(i, j - 1);
1112                             if (c1.Name != "ffffffff")
1113                                 intCount++;
1114                         }
1115                         else
1116                         {
1117                             intCount++;
1118                         }
1119                         //
1120                         if (j < bit.Height - 1)
1121                         {
1122                             Color c2 = bit.GetPixel(i, j + 1);
1123                             if (c2.Name != "ffffffff")
1124                                 intCount++;
1125                         }
1126                         else
1127                         {
1128                             intCount++;
1129                         }
1130                         //
1131                         if (i > 0)
1132                         {
1133                             Color c3 = bit.GetPixel(i - 1, j);
1134                             if (c3.Name != "ffffffff")
1135                                 intCount++;
1136                         }
1137                         else
1138                         {
1139                             intCount++;
1140                         }
1141                         //
1142                         if (i < bit.Width - 1)
1143                         {
1144                             Color c4 = bit.GetPixel(i + 1, j);
1145                             if (c4.Name != "ffffffff")
1146                                 intCount++;
1147                         }
1148                         else
1149                         {
1150                             intCount++;
1151                         }
1152 
1153                         if (intCount >= 3)
1154                         {
1155                             bit.SetPixel(i, j, Color.Black);
1156                         }
1157                     }
1158 
1159                 }
1160 
1161             }
1162             return bit;
1163         }
1164         #endregion
1165 
1166         #region 连通并识别
1167 
1168         /// <summary>
1169         /// 功能描述:识别字符
1170         /// 作  者:huangzh
1171         /// 创建日期:2016-09-02 09:06:44
1172         /// 任务编号:
1173         /// </summary>
1174         /// <param name="lstImage">lstImage</param>
1175         /// <returns>返回值</returns>
1176         private List<string> GetImageChar(List<Bitmap> lstImage)
1177         {
1178             string strPath = Path.Combine(m_strModePath, "imgs");
1179 
1180             List<string> lstKeys = new List<string>();
1181             Console.WriteLine("--------------");
1182             foreach (var item in lstImage)
1183             {
1184                 string strKey = GetTextByOneChar(item, strPath);
1185                 lstKeys.Add(strKey);
1186                 Console.WriteLine(strKey);
1187             }
1188 
1189             return lstKeys;
1190         }
1191 
1192         /// <summary>
1193         /// 功能描述:获取连通
1194         /// 作  者:huangzh
1195         /// 创建日期:2016-09-01 15:50:18
1196         /// 任务编号:
1197         /// </summary>
1198         /// <param name="bitImage">bitImage</param>
1199         /// <param name="minSize">最小连通域</param>
1200         /// <param name="blnIsCheckWidth">合并检测</param>
1201         /// <param name="intMaxWidth">当blnIsCheckWidth=true时,单个字符最大宽度</param>
1202         /// <param name="blnIsCheckMinWidth">是否旋转为最小宽度</param>
1203         /// <returns></returns>
1204         private List<Bitmap> GetLianTongImage(Bitmap bitImage)
1205         {
1206             string[] strSizeBiao = m_xml.ConvertIdToName("51").Split(',');
1207             Size minSize = new Size(int.Parse(strSizeBiao[0]), int.Parse(strSizeBiao[1]));
1208             bool blnIsCheckWidth = bool.Parse(m_xml.ConvertIdToName("52"));
1209             int intMaxWidth = int.Parse(m_xml.ConvertIdToName("53"));
1210             bool blnIsCheckMinWidth = bool.Parse(m_xml.ConvertIdToName("54"));
1211 
1212             Bitmap bit = bitImage.Clone(new Rectangle(0, 0, bitImage.Width, bitImage.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
1213             Bitmap imageCache = bitImage.Clone(new Rectangle(0, 0, bitImage.Width, bitImage.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
1214             // process image with blob counter
1215             BlobCounter blobCounter = new BlobCounter();
1216             blobCounter.ProcessImage(bit);
1217             Blob[] blobs = blobCounter.GetObjectsInformation();
1218 
1219             // create convex hull searching algorithm
1220             GrahamConvexHull hullFinder = new GrahamConvexHull();
1221 
1222             // lock image to draw on it
1223             BitmapData data = bit.LockBits(
1224                 new Rectangle(0, 0, bit.Width, bit.Height),
1225                     ImageLockMode.ReadWrite, bit.PixelFormat);
1226 
1227             Dictionary<Bitmap, int> lstBitNew = new Dictionary<Bitmap, int>();
1228 
1229             Dictionary<List<IntPoint>, int> lstedgePoints = new Dictionary<List<IntPoint>, int>();
1230 
1231             // process each blob
1232             foreach (Blob blob in blobs)
1233             {
1234                 List<IntPoint> leftPoints = new List<IntPoint>();
1235                 List<IntPoint> rightPoints = new List<IntPoint>();
1236                 List<IntPoint> edgePoints = new List<IntPoint>();
1237 
1238                 // get blob's edge points
1239                 blobCounter.GetBlobsLeftAndRightEdges(blob,
1240                     out leftPoints, out rightPoints);
1241 
1242                 edgePoints.AddRange(leftPoints);
1243                 edgePoints.AddRange(rightPoints);
1244 
1245                 // blob's convex hull
1246                 List<IntPoint> hull = hullFinder.FindHull(edgePoints);
1247 
1248 
1249 
1250                 lstedgePoints.Add(hull, GetMinX(hull));
1251             }
1252 
1253             List<List<IntPoint>> dicLstPoints = (from d in lstedgePoints
1254                                                  orderby d.Value ascending
1255                                                  select d.Key).ToList();
1256 
1257             if (blnIsCheckWidth)
1258             {
1259                 #region 检测连通域是否可合并
1260                 bool isBreak = false;
1261                 while (!isBreak)
1262                 {
1263                     isBreak = true;
1264 
1265                     int intKeyLength = dicLstPoints.Count;
1266                     for (int i = 0; i < intKeyLength; i++)
1267                     {
1268                         if (i != 0)
1269                         {
1270                             bool bln = CheckIsHeBing(dicLstPoints[i - 1], dicLstPoints[i], intMaxWidth);
1271                             if (bln)
1272                             {
1273                                 dicLstPoints[i].AddRange(dicLstPoints[i - 1]);
1274                                 dicLstPoints.RemoveAt(i - 1);
1275                                 isBreak = false;
1276                                 break;
1277                             }
1278                         }
1279 
1280                         if (i != intKeyLength - 1)
1281                         {
1282                             bool bln = CheckIsHeBing(dicLstPoints[i], dicLstPoints[i + 1], intMaxWidth);
1283                             if (bln)
1284                             {
1285                                 dicLstPoints[i].AddRange(dicLstPoints[i + 1]);
1286                                 dicLstPoints.RemoveAt(i + 1);
1287                                 isBreak = false;
1288                                 break;
1289                             }
1290                         }
1291                     }
1292                 }
1293                 #endregion
1294             }
1295 
1296             foreach (List<IntPoint> item in dicLstPoints)
1297             {
1298                 List<IntPoint> hull = hullFinder.FindHull(item);
1299                 int intMinX = 0;
1300                 Bitmap bitNew = GetBitmapByListPoint(hull, imageCache, ref intMinX);
1301                 if (bitNew.Width < minSize.Width || bitNew.Height < minSize.Height)
1302                     continue;
1303                 lstBitNew.Add(bitNew, intMinX);
1304                 Drawing.Polygon(data, hull, Color.Red);
1305             }
1306 
1307             bit.UnlockBits(data);
1308 
1309             Dictionary<Bitmap, int> dic1Asc1 = (from d in lstBitNew
1310                                                 orderby d.Value ascending
1311                                                 select d).ToDictionary(k => k.Key, v => v.Value);
1312 
1313             List<Bitmap> lstImage = new List<Bitmap>();
1314 
1315             foreach (var item in dic1Asc1)
1316             {
1317                 Bitmap bitItem = item.Key;
1318                 bitItem = ToResizeAndCenter(bitItem);
1319                 if (blnIsCheckMinWidth)
1320                 {
1321                     bitItem = GetMinWidthBitmap(bitItem);
1322                 }
1323                 lstImage.Add(bitItem);//添加图片    
1324             }
1325 
1326             return lstImage;
1327         }
1328 
1329         /// <summary>
1330         /// 功能描述:识别单数字
1331         /// 作  者:huangzh
1332         /// 创建日期:2016-08-25 15:19:35
1333         /// 任务编号:
1334         /// </summary>
1335         /// <param name="bit">bit</param>
1336         /// <param name="lstNoChar">lstNoChar</param>
1337         /// <returns>返回值</returns>
1338         private string GetTextByOneChar(Bitmap bit, string strSourceImagPath, List<string> lstNoChar = null)
1339         {
1340             bit = bit.Clone(new Rectangle(0, 0, bit.Width, bit.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
1341             var files = Directory.GetFiles(strSourceImagPath);
1342             if (lstNoChar != null && lstNoChar.Count > 0)
1343             {
1344                 var newFiles = from p in files
1345                                where !lstNoChar.Contains(Path.GetFileName(p).Split('_')[0])
1346                                select p;
1347                 files = newFiles.ToArray<string>();
1348             }
1349 
1350             var templateList = files.Select(i => { return new Bitmap(i); }).ToList();
1351             var templateListFileName = files.Select(i => { return Path.GetFileName(i); }).ToList();
1352 
1353             var result = new List<string>();
1354 
1355             ExhaustiveTemplateMatching templateMatching = new ExhaustiveTemplateMatching(0.8f);
1356 
1357             float max = 0;
1358             int index = 0;
1359 
1360             if (bit.Width <= 25 && bit.Height <= 25)
1361                 bit = ToResizeAndCenter(bit);
1362             //bit.Save("d:\111.jpg");
1363             for (int j = 0; j < templateList.Count; j++)
1364             {
1365                 var compare = templateMatching.ProcessImage(bit, templateList[j]);
1366                 //if (templateListFileName[index].StartsWith("%"))
1367                 //{
1368                 //    Console.WriteLine(templateListFileName[index]);
1369                 //}
1370                 if (compare.Length > 0 && compare[0].Similarity > max)
1371                 {
1372                     //记录下最相似的
1373                     max = compare[0].Similarity;
1374                     index = j;
1375                 }
1376             }
1377             if (templateListFileName.Count > 0)
1378                 return templateListFileName[index].Split('_')[0];
1379             else
1380                 return "";
1381         }
1382 
1383 
1384         /// <summary>
1385         /// 功能描述:得到最小x
1386         /// 作  者:huangzh
1387         /// 创建日期:2016-09-01 15:42:22
1388         /// 任务编号:
1389         /// </summary>
1390         /// <param name="hull">hull</param>
1391         /// <returns>返回值</returns>
1392         private int GetMinX(List<IntPoint> hull)
1393         {
1394             int x = int.MaxValue;
1395             foreach (IntPoint item in hull)
1396             {
1397                 if (item.X < x)
1398                     x = item.X;
1399             }
1400             return x;
1401         }
1402 
1403         /// <summary>
1404         /// 功能描述:检查是否需要合并(目前仅检查x方向合并)
1405         /// 作  者:huangzh
1406         /// 创建日期:2016-09-01 15:42:56
1407         /// 任务编号:
1408         /// </summary>
1409         /// <param name="lst1">lst1</param>
1410         /// <param name="lst2">lst2</param>
1411         /// <param name="intMaxWidth">intMaxWidth</param>
1412         /// <returns>返回值</returns>
1413         private bool CheckIsHeBing(List<IntPoint> lst1, List<IntPoint> lst2, int intMaxWidth)
1414         {
1415             int minx1 = int.MaxValue, minx2 = int.MaxValue;
1416             int maxx1 = int.MinValue, maxx2 = int.MinValue;
1417 
1418             foreach (IntPoint item in lst1)
1419             {
1420                 if (item.X > maxx1)
1421                     maxx1 = item.X;
1422                 if (item.X < minx1)
1423                     minx1 = item.X;
1424             }
1425 
1426             foreach (IntPoint item in lst2)
1427             {
1428                 if (item.X > maxx2)
1429                     maxx2 = item.X;
1430                 if (item.X < minx2)
1431                     minx2 = item.X;
1432             }
1433 
1434             int intCenter1 = minx1 + (maxx1 - minx1) / 2;
1435             int intCenter2 = minx2 + (maxx2 - minx2) / 2;
1436             if ((intCenter1 > minx2 && intCenter1 < maxx2) || (intCenter2 > minx1 && intCenter2 < maxx1))
1437             {
1438                 int _intMin = minx1 < minx2 ? minx1 : minx2;
1439                 int _intMax = maxx1 > maxx2 ? maxx1 : maxx2;
1440 
1441                 if (_intMax - _intMin > intMaxWidth)
1442                     return false;
1443                 else
1444                     return true;
1445             }
1446             else
1447                 return false;
1448         }
1449 
1450         /// <summary>
1451         /// 功能描述:根据坐标列表截图
1452         /// 作  者:huangzh
1453         /// 创建日期:2016-09-01 15:43:57
1454         /// 任务编号:
1455         /// </summary>
1456         /// <param name="hull">hull</param>
1457         /// <param name="bitImg">bitImg</param>
1458         /// <param name="_minX">_minX</param>
1459         /// <returns>返回值</returns>
1460         private Bitmap GetBitmapByListPoint(List<IntPoint> hull, Bitmap bitImg, ref int _minX)
1461         {
1462             int minx = int.MaxValue;
1463             int miny = int.MaxValue;
1464             int maxx = int.MinValue;
1465             int maxy = int.MinValue;
1466             foreach (IntPoint item in hull)
1467             {
1468                 if (item.X > maxx)
1469                     maxx = item.X;
1470                 if (item.X < minx)
1471                     minx = item.X;
1472 
1473                 if (item.Y > maxy)
1474                     maxy = item.Y;
1475                 if (item.Y < miny)
1476                     miny = item.Y;
1477             }
1478 
1479             Bitmap bit = new Bitmap(maxx - minx + 1, maxy - miny + 1);
1480             int bitImgWidth = bitImg.Width;
1481             int bitImgHeight = bitImg.Height;
1482             for (int i = minx; i <= maxx; i++)
1483             {
1484                 for (int j = miny; j <= maxy; j++)
1485                 {
1486                     Color c = bitImg.GetPixel(i, j);
1487                     if (c.R == 0)
1488                         c = Color.White;
1489                     else
1490                         c = Color.Black;
1491                     bit.SetPixel(i - minx, j - miny, c);
1492                 }
1493             }
1494             _minX = minx;
1495             // bit.Save("d:\1\" + Guid.NewGuid() + ".jpg");
1496             return bit;
1497         }
1498 
1499         /// <summary>
1500         /// 功能描述:图片放到中心
1501         /// 作  者:huangzh
1502         /// 创建日期:2016-08-25 15:16:42
1503         /// 任务编号:
1504         /// </summary>
1505         /// <param name="bit">bit</param>
1506         /// <param name="w">w</param>
1507         /// <param name="h">h</param>
1508         /// <returns>返回值</returns>
1509         private Bitmap ToResizeAndCenter(Bitmap bit)
1510         {
1511             bit = bit.Clone(new Rectangle(0, 0, bit.Width, bit.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
1512 
1513             bit = new Invert().Apply(bit);
1514 
1515             int sw = bit.Width;
1516             int sh = bit.Height;
1517 
1518             int w, h;
1519             if (sw < 25 && sh < 25)
1520             {
1521                 w = 25;
1522                 h = 25;
1523             }
1524             else
1525             {
1526                 w = sw + 5;
1527                 h = sh + 5;
1528             }
1529 
1530 
1531             Crop corpFilter = new Crop(new Rectangle(0, 0, w, h));
1532 
1533             bit = corpFilter.Apply(bit);
1534 
1535             //再反转回去
1536             bit = new Invert().Apply(bit);
1537 
1538             //计算中心位置
1539             int centerX = (w - sw) / 2;
1540             int centerY = (h - sh) / 2;
1541 
1542             bit = new CanvasMove(new IntPoint(centerX, centerY), Color.White).Apply(bit);
1543             return bit;
1544         }
1545 
1546         /// <summary>
1547         /// 功能描述:得到左右30度最窄的图片
1548         /// 作  者:huangzh
1549         /// 创建日期:2016-08-25 14:58:32
1550         /// 任务编号:
1551         /// </summary>
1552         /// <param name="bitImg">bitImg</param>
1553         /// <returns>返回值</returns>
1554         private Bitmap GetMinWidthBitmap(Bitmap bitImg, float fltNum = 15)
1555         {
1556             Bitmap bitCache = bitImg;
1557             for (float i = fltNum * -1; i < fltNum; i++)
1558             {
1559                 if (i == 0)
1560                     continue;
1561                 Bitmap bit1 = bitImg.Clone(new Rectangle(0, 0, bitImg.Width, bitImg.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
1562                 Bitmap bit2 = RotateImage(bit1, i);
1563                 Bitmap bit3 = GetMinBitmap(bit2);
1564                 if (bit3.Width < bitCache.Width)
1565                 {
1566                     bitCache = bit3;
1567                 }
1568                 else
1569                 {
1570                     bit3.Dispose();
1571                 }
1572             }
1573             return bitCache;
1574         }
1575 
1576         /// <summary>
1577         /// 功能描述:缩小图片
1578         /// 作  者:huangzh
1579         /// 创建日期:2016-08-25 14:55:46
1580         /// 任务编号:
1581         /// </summary>
1582         /// <param name="bit">bit</param>
1583         /// <returns>返回值</returns>
1584         private Bitmap GetMinBitmap(Bitmap bit)
1585         {
1586             int x1 = 0, y1 = 0;
1587             int x2 = 0, y2 = 0;
1588             GetXY(bit, ref x1, ref y1, ref x2, ref y2);
1589             Bitmap bit11 = bit.Clone(new Rectangle(x1, y1, x2 - x1 + 1, y2 - y1 + 1), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
1590             return bit11;
1591         }
1592 
1593         /// <summary>
1594         /// 功能描述:旋转图片
1595         /// 作  者:huangzh
1596         /// 创建日期:2016-08-25 14:57:11
1597         /// 任务编号:
1598         /// </summary>
1599         /// <param name="b">b</param>
1600         /// <param name="angle">angle</param>
1601         /// <returns>返回值</returns>
1602         private Bitmap RotateImage(Bitmap b, float angle)
1603         {
1604             //对黑白进行颜色反转
1605             b = ColorFanZhuan(b);
1606             RotateNearestNeighbor filter = new RotateNearestNeighbor(angle, true);
1607             Bitmap bnew = filter.Apply(b);
1608             bnew = ColorFanZhuan(bnew);
1609             return bnew;
1610         }
1611 
1612         /// <summary>
1613         /// 功能描述:获得最大最小xy
1614         /// 作  者:huangzh
1615         /// 创建日期:2016-08-25 14:55:56
1616         /// 任务编号:
1617         /// </summary>
1618         /// <param name="bit">bit</param>
1619         /// <param name="x1">x1</param>
1620         /// <param name="y1">y1</param>
1621         /// <param name="x2">x2</param>
1622         /// <param name="y2">y2</param>
1623         private void GetXY(
1624             Bitmap bit,
1625             ref  int x1,
1626             ref  int y1,
1627             ref  int x2,
1628             ref int y2)
1629         {
1630             bool bln = false;
1631             #region 最小X
1632             for (int i = 0; i < bit.Width; i++)
1633             {
1634                 for (int j = 0; j < bit.Height; j++)
1635                 {
1636                     Color c = bit.GetPixel(i, j);
1637                     if (c.Name != "ffffffff")
1638                     {
1639                         x1 = i;
1640                         bln = true;
1641                         break;
1642                     }
1643                 }
1644                 if (bln)
1645                 {
1646                     break;
1647                 }
1648             }
1649             #endregion
1650             #region 最大X
1651             bln = false;
1652             for (int i = bit.Width - 1; i >= 0; i--)
1653             {
1654                 for (int j = 0; j < bit.Height; j++)
1655                 {
1656                     Color c = bit.GetPixel(i, j);
1657                     if (c.Name != "ffffffff")
1658                     {
1659                         x2 = i;
1660                         bln = true;
1661                         break;
1662                     }
1663                 }
1664                 if (bln)
1665                 {
1666                     break;
1667                 }
1668             }
1669             #endregion
1670             #region 最小Y
1671             bln = false;
1672             for (int j = 0; j < bit.Height; j++)
1673             {
1674                 for (int i = 0; i < bit.Width; i++)
1675                 {
1676                     Color c = bit.GetPixel(i, j);
1677                     if (c.Name != "ffffffff")
1678                     {
1679                         y1 = j;
1680                         bln = true;
1681                         break;
1682                     }
1683                 }
1684                 if (bln)
1685                 {
1686                     break;
1687                 }
1688             }
1689             #endregion
1690             #region 最大Y
1691             bln = false;
1692             for (int j = bit.Height - 1; j >= 0; j--)
1693             {
1694                 for (int i = 0; i < bit.Width; i++)
1695                 {
1696                     Color c = bit.GetPixel(i, j);
1697                     if (c.Name != "ffffffff")
1698                     {
1699                         y2 = j;
1700                         bln = true;
1701                         break;
1702                     }
1703                 }
1704                 if (bln)
1705                 {
1706                     break;
1707                 }
1708             }
1709             #endregion
1710         }
1711         #endregion
1712 
1713         #region 细化图片
1714         /// <summary>
1715         /// 功能描述:细化图片
1716         /// 作  者:huangzh
1717         /// 创建日期:2016-09-01 16:07:13
1718         /// 任务编号:
1719         /// </summary>
1720         /// <param name="bitImage">bitImage</param>
1721         /// <returns>返回值</returns>
1722         private Bitmap XiHuaBitMap(Bitmap bitImage)
1723         {
1724             Bitmap bit = bitImage.Clone(new Rectangle(0, 0, bitImage.Width, bitImage.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
1725             bit = XiHua.Xihua(bit, XiHua.array);
1726             return bit;
1727         }
1728         #endregion
1729 
1730         #region 膨胀
1731         /// <summary>
1732         /// 功能描述:膨胀
1733         /// 作  者:huangzh
1734         /// 创建日期:2016-09-01 16:08:21
1735         /// 任务编号:
1736         /// </summary>
1737         /// <param name="bitImage">bitImage</param>
1738         /// <returns>返回值</returns>
1739         private Bitmap PangZhang(Bitmap bitImage)
1740         {
1741             Bitmap bit = bitImage.Clone(new Rectangle(0, 0, bitImage.Width, bitImage.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
1742             Dilatation filter = new Dilatation();
1743             // apply the filter
1744             bit = filter.Apply(bit);
1745             return bit;
1746         }
1747         #endregion
1748 
1749         #region 倒影分割
1750 
1751         /// <summary>
1752         /// 功能描述:获取图片投影分割
1753         /// 作  者:huangzh
1754         /// 创建日期:2016-09-09 12:20:54
1755         /// 任务编号:
1756         /// </summary>
1757         /// <param name="bitImage">bitImage</param>
1758         /// <param name="bitBase">bitBase</param>
1759         /// <param name="intRemove">1/2</param>
1760         /// <returns>返回值</returns>
1761         private List<Bitmap> GetTouYingImages(Bitmap bitImage, Bitmap bitBase, int intRemove = 2)
1762         {
1763             Bitmap bit = bitImage.Clone(new Rectangle(0, 0, bitImage.Width, bitImage.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
1764             bool blnCheckDG = bool.Parse(m_xml.ConvertIdToName("61", "false"));
1765             int intMaxDG = int.Parse(m_xml.ConvertIdToName("62", "3"));
1766             bool blnCheckWidth = bool.Parse(m_xml.ConvertIdToName("63", "false"));
1767             int intMaxWidth = int.Parse(m_xml.ConvertIdToName("64", "25"));
1768 
1769             HorizontalIntensityStatistics his = new HorizontalIntensityStatistics(bit);
1770             Histogram histogram = his.Blue;
1771             List<Rectangle> lstRects = new List<Rectangle>();
1772             int intWidth = bit.Width;
1773             int intHeight = bit.Height;
1774             bool blnHasValue = false;
1775             int intStartX = 0, intEndx = 0;
1776             for (int i = 0; i < histogram.Values.Length; i++)
1777             {
1778                 if (histogram.Values[i] == 0 || (blnCheckDG && histogram.Values[i] <= intMaxDG * 256))
1779                 {
1780                     if (blnHasValue)
1781                     {
1782                         intEndx = i;
1783                         blnHasValue = false;
1784                         lstRects.Add(new Rectangle(intStartX, 0, intEndx - intStartX, intHeight));
1785                     }
1786                 }
1787                 else
1788                 {
1789                     if (!blnHasValue)
1790                     {
1791                         intStartX = i;
1792                         blnHasValue = true;
1793                     }
1794                 }
1795             }
1796             if (blnHasValue)
1797             {
1798                 lstRects.Add(new Rectangle(intStartX, 0, intWidth - intStartX, intHeight));
1799             }
1800 
1801             Dictionary<Bitmap, Rectangle> lstBits = new Dictionary<Bitmap, Rectangle>();
1802             lstRects.ForEach(item => lstBits.Add(bit.Clone(item, System.Drawing.Imaging.PixelFormat.Format24bppRgb), item));
1803 
1804             //特殊处理,移除最后2个
1805             List<Bitmap> lstKeys = lstBits.Keys.ToList();
1806             bool blnChaoKuan1 = false;
1807             if (lstKeys[lstKeys.Count - 1].Width > intMaxWidth - 5)
1808                 blnChaoKuan1 = true;
1809             if (lstKeys[lstKeys.Count - 1].Width > 2 * intMaxWidth)
1810                 intRemove = 1;
1811             lstBits.Remove(lstKeys[lstKeys.Count - 1]);
1812             if (intRemove == 2)
1813             {
1814                 bool blnChaoKuan2 = false;
1815                 if (lstKeys[lstKeys.Count - 2].Width > intMaxWidth - 5)
1816                     blnChaoKuan2 = true;
1817                 if (!(blnChaoKuan1 && blnChaoKuan2))
1818                     lstBits.Remove(lstKeys[lstKeys.Count - 2]);
1819             }
1820 
1821             List<Bitmap> lstImages = new List<Bitmap>();
1822             if (blnCheckWidth)
1823             {
1824                 foreach (var item in lstBits)
1825                 {
1826                     if (item.Key.Width >= intMaxWidth)
1827                     {
1828                         int intColorCount = 0;
1829                         Bitmap bitNew = HuiFuColorByImage(item.Key, bitBase, item.Value, ref intColorCount);
1830                         int intSpliteNum = bitNew.Width / intMaxWidth + ((bitNew.Width % intMaxWidth) > 0 ? 1 : 0);
1831 
1832                         Bitmap[] images = ImageJuLei(bitNew, intSpliteNum, intColorCount);
1833 
1834                         //去噪
1835 
1836 
1837                         List<Bitmap> lstImageNew = ImageOrder(images);
1838                         foreach (var itemImage in lstImageNew)
1839                         {
1840                             lstImages.Add(GetMinBitmap(ColorFanZhuan(itemImage)));//需要做去噪
1841                         }
1842                     }
1843                     else
1844                     {
1845                         lstImages.Add(GetMinBitmap(ColorFanZhuan(item.Key)));//需要做去噪
1846                     }
1847                 }
1848             }
1849 
1850 
1851             List<Bitmap> lstReturn = new List<Bitmap>();
1852 
1853             foreach (var item in lstImages)
1854             {
1855                 Bitmap bitItem = item;
1856                 bitItem = ToResizeAndCenter(bitItem);
1857                 if (bitItem.Width > 25 || bitItem.Height > 25)
1858                 {
1859                     bitItem = new Bitmap(bitItem, new Size(25, 25));
1860                 }
1861                 lstReturn.Add(bitItem);//添加图片    
1862             }
1863 
1864             return lstReturn;
1865         }
1866 
1867 
1868         /// <summary>
1869         /// 功能描述:图片排序
1870         /// 作  者:huangzh
1871         /// 创建日期:2016-09-08 17:44:21
1872         /// 任务编号:
1873         /// </summary>
1874         /// <param name="images">images</param>
1875         /// <returns>返回值</returns>
1876         private List<Bitmap> ImageOrder(Bitmap[] images)
1877         {
1878             Dictionary<int, int> lst = new Dictionary<int, int>();
1879 
1880             for (int m = 0; m < images.Length; m++)
1881             {
1882                 Bitmap bit = images[m];
1883                 int intWidth = bit.Width;
1884                 int intHeight = bit.Height;
1885                 bool blnBreak = false;
1886                 int intMinX = 0;
1887                 for (int i = 0; i < intWidth; i++)
1888                 {
1889                     for (int j = 0; j < intHeight; j++)
1890                     {
1891                         Color c = bit.GetPixel(i, j);
1892                         if (c.Name == "ffffffff")
1893                         {
1894                             blnBreak = true;
1895                             intMinX = i;
1896                             break;
1897                         }
1898                     }
1899                     if (blnBreak)
1900                         break;
1901                 }
1902                 lst.Add(m, intMinX);
1903             }
1904 
1905             Dictionary<int, int> lstNew = (from d in lst
1906                                            orderby d.Value
1907                                            select d).ToDictionary(k => k.Key, v => v.Value);
1908             List<Bitmap> lstImage = new List<Bitmap>();
1909             foreach (var item in lstNew)
1910             {
1911                 lstImage.Add(images[item.Key]);
1912             }
1913             return lstImage;
1914         }
1915 
1916         /// <summary>
1917         /// 功能描述:恢复图片原色
1918         /// 作  者:huangzh
1919         /// 创建日期:2016-09-08 17:44:10
1920         /// 任务编号:
1921         /// </summary>
1922         /// <param name="bitImage">bitImage</param>
1923         /// <param name="bitSource">bitSource</param>
1924         /// <param name="rect">rect</param>
1925         /// <param name="intColorCount">intColorCount</param>
1926         /// <returns>返回值</returns>
1927         private Bitmap HuiFuColorByImage(
1928             Bitmap bitImage,
1929             Bitmap bitSource,
1930             Rectangle rect,
1931             ref int intColorCount)
1932         {
1933             intColorCount = 0;
1934             int intWidth = bitImage.Width;
1935             int intHeight = bitImage.Height;
1936             for (int i = 0; i < intWidth; i++)
1937             {
1938                 for (int j = 0; j < intHeight; j++)
1939                 {
1940                     Color c = bitImage.GetPixel(i, j);
1941                     if (c.Name == "ffffffff")
1942                     {
1943                         intColorCount++;
1944                         bitImage.SetPixel(i, j, bitSource.GetPixel(i + rect.X, j + rect.Y));
1945                     }
1946                 }
1947             }
1948             return bitImage;
1949         }
1950 
1951 
1952         /// <summary>
1953         /// 功能描述:颜色聚类分割图片
1954         /// 作  者:huangzh
1955         /// 创建日期:2016-09-08 17:43:58
1956         /// 任务编号:
1957         /// </summary>
1958         /// <param name="bit">bit</param>
1959         /// <param name="intNum">intNum</param>
1960         /// <param name="intColorCount">intColorCount</param>
1961         /// <returns>返回值</returns>
1962         private Bitmap[] ImageJuLei(Bitmap bit, int intNum, int intColorCount)
1963         {
1964             Color[] colors;
1965             List<Color> _lst = new List<Color>();
1966             int intWidth = bit.Width;
1967             int intHeight = bit.Height;
1968             int intColorIndex = 0;
1969             for (int i = 0; i < intWidth; i++)
1970             {
1971                 for (int j = 0; j < intHeight; j++)
1972                 {
1973                     Color c = bit.GetPixel(i, j);
1974                     if (c.R != 0 && c.G != 0 && c.B != 0)
1975                     {
1976                         _lst.Add(c);
1977                         intColorIndex++;
1978                     }
1979                 }
1980             }
1981             colors = _lst.ToArray();
1982             int k = intNum;
1983             Color[][] g;
1984             g = KmeansColor.cluster(colors, k);
1985             List<List<Color>> lstColors = new List<List<Color>>();
1986 
1987             foreach (var item in g)
1988             {
1989                 List<Color> lst = new List<Color>();
1990                 foreach (var item1 in item)
1991                 {
1992                     Color c = item1;
1993 
1994                     if (!lst.Contains(c))
1995                     {
1996                         lst.Add(c);
1997                     }
1998                 }
1999                 lstColors.Add(lst);
2000             }
2001 
2002             Bitmap[] bits = new Bitmap[intNum];
2003             for (int m = 0; m < lstColors.Count; m++)
2004             {
2005                 List<Color> lst = lstColors[m];
2006                 Bitmap bitNew = bit.Clone(new Rectangle(0, 0, bit.Width, bit.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
2007                 int intWidthNew = bitNew.Width;
2008                 int intHeightNew = bitNew.Height;
2009                 for (int i = 0; i < intWidthNew; i++)
2010                 {
2011                     for (int j = 0; j < intHeightNew; j++)
2012                     {
2013                         Color cNew = bitNew.GetPixel(i, j);
2014                         if (cNew.R != 0 && cNew.G != 0 && cNew.B != 0)
2015                         {
2016                             if (!lst.Contains(cNew))
2017                             {
2018                                 bitNew.SetPixel(i, j, Color.Black);
2019                             }
2020                             else
2021                             {
2022                                 bitNew.SetPixel(i, j, Color.White);
2023                             }
2024                         }
2025                     }
2026                 }
2027                 bitNew = QuZao(bitNew);
2028                 bits[m] = bitNew;
2029             }
2030 
2031             return bits;
2032         }
2033 
2034         #endregion
2035 
2036         private static class XiHua
2037         {
2038             public static int[] array = {0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,
2039                                       1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,
2040                                       0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,
2041                                       1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,
2042                                       1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,
2043                                       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2044                                       1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,1,
2045                                       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2046                                       0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,
2047                                       1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,
2048                                       0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,
2049                                       1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
2050                                       1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,
2051                                       1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
2052                                       1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,0,
2053                                       1,1,0,0,1,1,1,0,1,1,0,0,1,0,0,0};
2054 
2055             public static bool isWhite(Color color)
2056             {
2057                 if (color.R + color.G + color.B > 400)
2058                 {
2059                     return true;
2060                 }
2061                 return false;
2062             }
2063 
2064             public static Bitmap VThin(Bitmap image, int[] array)
2065             {
2066                 int h = image.Height;
2067                 int w = image.Width;
2068                 int NEXT = 1;
2069                 for (int i = 0; i < h; i++)
2070                 {
2071                     for (int j = 0; j < w; j++)
2072                     {
2073                         if (NEXT == 0)
2074                         {
2075                             NEXT = 1;
2076                         }
2077                         else
2078                         {
2079                             int M;
2080                             if (0 < j && j < w - 1)
2081                             {
2082                                 if (isBlack(image.GetPixel(j - 1, i)) && isBlack(image.GetPixel(j, i)) && isBlack(image.GetPixel(j + 1, i)))
2083                                 {    // 三个点都为黑色的时候M=0,否则M=1
2084                                     M = 0;
2085                                 }
2086                                 else
2087                                 {
2088                                     M = 1;
2089                                 }
2090                             }
2091                             else
2092                             {
2093                                 M = 1;
2094                             }
2095                             if (isBlack(image.GetPixel(j, i)) && M != 0)
2096                             {
2097                                 int[] a = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2098                                 for (int k = 0; k < 3; k++)
2099                                 {
2100                                     for (int l = 0; l < 3; l++)
2101                                     {
2102                                         if ((-1 < (i - 1 + k) && (i - 1 + k) < h) && (-1 < (j - 1 + l) && (j - 1 + l) < w) && isWhite(image.GetPixel(j - 1 + l, i - 1 + k)))
2103                                         {
2104                                             a[k * 3 + l] = 1;
2105                                         }
2106                                     }
2107                                 }
2108                                 int sum = a[0] * 1 + a[1] * 2 + a[2] * 4 + a[3] * 8 + a[5] * 16 + a[6] * 32 + a[7] * 64 + a[8] * 128;
2109                                 if (array[sum] == 0)
2110                                 {
2111                                     image.SetPixel(j, i, Color.Black);
2112                                 }
2113                                 else
2114                                 {
2115                                     image.SetPixel(j, i, Color.White);
2116                                 }
2117                                 if (array[sum] == 1)
2118                                 {
2119                                     NEXT = 0;
2120                                 }
2121                             }
2122                         }
2123                     }
2124                 }
2125                 return image;
2126             }
2127 
2128             public static Bitmap HThin(Bitmap image, int[] array)
2129             {
2130                 int h = image.Height;
2131                 int w = image.Width;
2132                 int NEXT = 1;
2133                 for (int j = 0; j < w; j++)
2134                 {
2135                     for (int i = 0; i < h; i++)
2136                     {
2137                         if (NEXT == 0)
2138                         {
2139                             NEXT = 1;
2140                         }
2141                         else
2142                         {
2143                             int M;
2144                             if (0 < i && i < h - 1)
2145                             {
2146                                 if (isBlack(image.GetPixel(j, i - 1)) && isBlack(image.GetPixel(j, i)) && isBlack(image.GetPixel(j, i + 1)))
2147                                 {
2148                                     M = 0;
2149                                 }
2150                                 else
2151                                 {
2152                                     M = 1;
2153                                 }
2154                             }
2155                             else
2156                             {
2157                                 M = 1;
2158                             }
2159                             if (isBlack(image.GetPixel(j, i)) && M != 0)
2160                             {
2161                                 int[] a = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2162                                 for (int k = 0; k < 3; k++)
2163                                 {
2164                                     for (int l = 0; l < 3; l++)
2165                                     {
2166                                         if ((-1 < (i - 1 + k) && (i - 1 + k) < h) && (-1 < (j - 1 + l) && (j - 1 + l) < w) && isWhite(image.GetPixel(j - 1 + l, i - 1 + k)))
2167                                         {
2168                                             a[k * 3 + l] = 1;
2169                                         }
2170                                     }
2171                                 }
2172                                 int sum = a[0] * 1 + a[1] * 2 + a[2] * 4 + a[3] * 8 + a[5] * 16 + a[6] * 32 + a[7] * 64 + a[8] * 128;
2173                                 if (array[sum] == 0)
2174                                 {
2175                                     image.SetPixel(j, i, Color.Black);
2176                                 }
2177                                 else
2178                                 {
2179                                     image.SetPixel(j, i, Color.White);
2180                                 }
2181                                 if (array[sum] == 1)
2182                                 {
2183                                     NEXT = 0;
2184                                 }
2185                             }
2186                         }
2187                     }
2188                 }
2189                 return image;
2190             }
2191 
2192             public static Bitmap Xihua(Bitmap image, int[] array)
2193             {
2194                 image = image.Clone(new Rectangle(0, 0, image.Width, image.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
2195                 int num = 10;
2196                 Bitmap iXihua = image;
2197                 for (int i = 0; i < num; i++)
2198                 {
2199                     VThin(iXihua, array);
2200                     HThin(iXihua, array);
2201                 }
2202                 return iXihua;
2203             }
2204 
2205 
2206             public static bool isBlack(Color color)
2207             {
2208                 if (color.R + color.G + color.B <= 600)
2209                 {
2210                     return true;
2211                 }
2212                 return false;
2213             }
2214 
2215         }
2216     }
2217 }
View Code

备忘

原文地址:https://www.cnblogs.com/bfyx/p/5857602.html