Chinaunix首页 | 论坛 | 博客
  • 博客访问: 237545
  • 博文数量: 127
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1545
  • 用 户 组: 普通用户
  • 注册时间: 2013-03-17 01:33
个人简介

知码网伴您成长

文章分类

全部博文(127)

文章存档

2015年(10)

2014年(4)

2013年(113)

我的朋友

分类: C/C++

2013-05-05 21:33:55

 现在用c#做程序越来越流行了,很多人都将它作为了自己的第一编程语言,因为它的方便快速的开发能力得到了不少人的青睐。使用C#进行的识别有许多种方法,

下面是一段C#写成的程序,里面用到了一些技巧,其实做过的人都知道,不太清楚的看一下代码,注释都给出来了,很好理解的。

 using System; 

   using System.Collections.Generic;

   using System.Linq; 

   using System.Text; 

   using System.Drawing; 

   using System.IO; 

   using System.Configuration; 

   namespace ConsoleApplication4 

   { 

       ///

 

       /// 根据样本做验证码破解 

       ///  

       /// 需要在.config文件中的appSettings配置节中添加keysampleOcr.sampleDir value设置为样本图片所在路径 

       /// 验证码: 

       ///  

       /// outofmemory.cn 20120427 

       /// 100个样例准确数为88个,错误主要发生在389这三个字符的混淆上 

       ///

 

       public abstract class SampleOcr 

       { 

           ///

 

           /// 灰度中间值 

           ///

 

           static int MiddleGrayValue =200; 

    

           ///

 

           /// 分割图片的差异容忍度 

           ///

 

           static int ColorToleranceForSplit = 30;

           ///

 

           /// 样本字典 

           ///

 

           static Dictionary _samples; 

           ///

 

           /// 破解验证码 

           ///

 

           /// 验证码图片 

           /// 验证码文本 

           public static string Ocr(Bitmap bm)

           { 

                //做灰度处理 

                GrayByPixels(bm);       

                bm =RemoveVerticalSpaceRegion(bm);       

                Bitmap[] splitBms =SplitBitmaps(bm);        

                char[] result = newchar[splitBms.Length]; 

                for (int i = 0; i  

                { 

                    result[i] =OcrChar(splitBms[i]); 

                    splitBms[i].Dispose(); 

               } 

                return new string(result); 

           }       

           ///

 

           /// 分割图片 

           ///

 

           /// 图片 

           /// 分割后的图片对象 

           static Bitmap[] SplitBitmaps(Bitmap bm)

           { 

                //找出垂直分割线 

                List removeXs = newList(); 

                for (int x = 0; x  

                { 

                    bool hasDiffPoint =false; 

                    Color color =Color.White; 

                    for (int y = 0; y  

                    { 

                        if (y == 0) 

                        { 

                            color =bm.GetPixel(x, y); 

                        } 

                        else 

                        { 

                            Color currentColor = bm.GetPixel(x,y); 

                            int diff =CalculateColorDifference(currentColor, color);

                            if (diff >ColorToleranceForSplit) 

                            { 

                                hasDiffPoint = true; 

                                break; 

                            } 

                            // color =currentColor; 

                        } 

                    }       

                    if (!hasDiffPoint) 

                    { 

                        removeXs.Add(x); 

                    } 

                }       

                //根据空白区域,计算各个字符的位图           

                List charRects= new List(); 

                for (int i = 1; i  

                { 

                    int diff = removeXs[i] -removeXs[i - 1]; 

                    if (diff > 5) 

                    { 

                        if (diff >= 20) 

                        { 

                            Rectangle rect = newRectangle(removeXs[i - 1], 0, diff / 2, bm.Height); 

                           charRects.Add(rect); 

    

                            rect = newRectangle(removeXs[i - 1] + diff / 2, 0, diff / 2, bm.Height); 

                           charRects.Add(rect); 

                        } 

                        else 

                        { 

                            Rectangle rect =new Rectangle(removeXs[i - 1], 0, diff, bm.Height); 

                           charRects.Add(rect); 

                        } 

                    } 

                }       

                int count =charRects.Count; 

                Bitmap[] charBms = newBitmap[count]; 

                int charBmIndex = 0; 

                foreach (Rectangle item incharRects) 

                { 

                    Bitmap bmChar =bm.Clone(item, bm.PixelFormat); 

                    charBms[charBmIndex] =bmChar; 

                    charBmIndex += 1; 

               } 

                return charBms; 

           }       

           ///

 

           /// 解析字符 

           ///

 

           /// 分割后的小图 

           /// 字符 

           static char OcrChar(Bitmap bm) 

           { 

                Dictionary samples = LoadSamples();      

                double diff = .0; 

                string mayBe = null; 

                foreach (string key insamples.Keys) 

                { 

                    double diffRate =CalcImageDiffRate(samples[key], bm); 

                    if (diffRate == 1) 

                        return key[0];       

                    if (diffRate >diff) 

                    { 

                        mayBe = key; 

                        diff = diffRate; 

                    } 

                }       

                if (mayBe == null) throw newApplicationException();      

                return mayBe[0]; 

           }       

           ///

 

           /// 载入样本字典 

           ///

 

           /// 样本字典 

           private static Dictionary LoadSamples() 

           { 

                if (_samples == null) 

                { 

                    _samples = newDictionary(); 

                    string sampleDir =ConfigurationManager.AppSettings["sampleOcr.sampleDir"] ??@"D:\SampleOcr\samples"; 

                    DirectoryInfo dirInfo = newDirectoryInfo(sampleDir); 

                    FileInfo[] files =dirInfo.GetFiles("*.jpg"); 

                    foreach (FileInfo item in files) 

                    { 

                        Bitmap bm =(Bitmap)Bitmap.FromFile(item.FullName); 

                        string key =Path.GetFileNameWithoutExtension(item.FullName); 

                        _samples.Add(key,bm); 

                    } 

                }      

                return _samples; 

           }      

           ///

 

           /// 根据RGB,计算灰度值 

           ///

 

           /// Color 

           /// 灰度值,整型 

           static int GetGrayNumColor(System.Drawing.Color posClr) 

           { 

                return (posClr.R * 19595 +posClr.G * 38469 + posClr.B * 7472) >> 16; 

           }       

           ///

 

           /// 灰度转换,逐点方式

           ///

 

           static void GrayByPixels(Bitmap bm)

           { 

                for (int i = 0; i  

                { 

                    for (int j = 0; j  

                    { 

                        int tmpValue =GetGrayNumColor(bm.GetPixel(j, i)); 

                        bm.SetPixel(j, i,Color.FromArgb(tmpValue, tmpValue, tmpValue));

                    } 

               } 

           }       

           ///

 

           /// 删除垂直方向上的空白区域 

           ///

 

           /// 源图片 

           /// 删除空白之后的图片 

           static Bitmap RemoveVerticalSpaceRegion(Bitmap bm) 

           { 

                int topSpaceHeight = 0; 

                for (int y = 0; y  

                { 

                    bool hasDiffPoint =false; 

                    Color color =Color.White; 

                    for (int x = 0; x  

                    { 

                        if (x == 0) 

                        { 

                            color =bm.GetPixel(x, y); 

                        } 

                        else 

                        { 

                            Color currentColor= bm.GetPixel(x, y); 

                            int diff =CalculateColorDifference(currentColor, color);

                            if (diff >ColorToleranceForSplit) 

                            { 

                                hasDiffPoint =true; 

                                break; 

                            } 

                        } 

                    }       

                    if (hasDiffPoint) 

                    { 

                        break; 

                    } 

                    else 

                    { 

                        topSpaceHeight +=1; 

                    } 

                }      

                int bottomSpaceHeight = 0; 

                for (int y = bm.Height - 1; y> 0; y--) 

                { 

                    bool hasDiffPoint =false; 

                    Color color =Color.White; 

                    for (int x = 0; x  

                    { 

                        if (x == 0) 

                        { 

                            color =bm.GetPixel(x, y); 

                        } 

                        else 

                        { 

                            Color currentColor= bm.GetPixel(x, y); 

                            int diff =CalculateColorDifference(currentColor, color);

                            if (diff >ColorToleranceForSplit) 

                            { 

                                hasDiffPoint =true; 

                                break;

                            } 

                            color =currentColor; 

                        } 

                    } 

    

                    if (hasDiffPoint) 

                    { 

                        break; 

                    } 

                    else 

                    { 

                        bottomSpaceHeight +=1; 

                    } 

                }       

                Rectangle rectValid = newRectangle(0, topSpaceHeight, bm.Width, bm.Height - topSpaceHeight -bottomSpaceHeight); 

                Bitmap newBm =bm.Clone(rectValid, bm.PixelFormat); 

                bm.Dispose(); 

                return newBm; 

           }       

           private static double CalcImageDiffRate(Bitmap bmSample, BitmapbmCalc) 

           { 

                int[] eSample = newint[bmSample.Height]; 

                int[] eCalc = newint[bmSample.Height]; 

                for (int y = 0; y  

                { 

                   eSample[y] =GetHorizontalValue(bmSample, y); 

                    eCalc[y] =GetHorizontalValue(bmCalc, y); 

                } 

                return GetCosine(eSample,eCalc); 

           }      

           ///

 

           /// 获得向量的cos

           ///

 

           ///  

           ///  

           ///

           static double GetCosine(int[] e1, int[] e2) 

           { 

                double fenzi = 0; 

                for (int i = 0; i  

                { 

                    fenzi += e1[i] *e2[i]; 

                }      

                double fenmuLeft = 0; 

                double fenmuRight = 0; 

               for (int i = 0; i  

                { 

                    fenmuLeft += e1[i] *e1[i]; 

                    fenmuRight += e2[i] *e2[i]; 

                }       

                double fenmu =Math.Sqrt(fenmuLeft) * Math.Sqrt(fenmuRight);

                if (fenmu == 0.0) return0;       

                return fenzi / fenmu; 

           }      

           ///

 

           /// 计算水平方向上的差异点数 

           ///

 

           /// 位图 

           /// y坐标值 

           /// 差异点数 

           private static int GetHorizontalValue(Bitmap bm, int y) 

           { 

                if (y >= bm.Height) return0; 

                int val = 0; 

                for (int x = 0; x  

                { 

                    Color color =bm.GetPixel(x, y);       

                    int grayVal =GetColorGrayValue(color); 

                    if (grayVal >MiddleGrayValue) 

                    { 

                        val |= (1 < 

                    } 

                } 

                return val; 

           }      

           static int GetColorGrayValue(Color color) 

           { 

                return (int)(.299 * color.R +.587 * color.G + .114 * color.B); 

           }       

           ///

 

           /// 计算颜色之间的差值,这个只是一个简单的计算,真正的色差计算很复杂 

           ///

 

           /// A 

           /// B 

           /// 差值 

           static int CalculateColorDifference(Color colorA, Color colorB) 

           { 

                int diff =GetColorGrayValue(colorA) - GetColorGrayValue(colorB); 

                return Math.Abs(diff); 

           } 

       } 

} 

阅读(3199) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~