程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> c#驗證碼識別、圖片二值化、分割、分類、識別

c#驗證碼識別、圖片二值化、分割、分類、識別

編輯:C#入門知識

c# 驗證碼的識別主要分為預處理、分割、識別三個步驟

首先我從網站上下載驗證碼

處理結果如下:

\


1.圖片預處理,即二值化圖片

*就是將圖像上的像素點的灰度值設置為0或255。

原理如下:

\


代碼如下:

#region 二值化圖片
        /// 
        /// 二值化圖片
        /// 就是將圖像上的像素點的灰度值設置為0或255
        /// 
        /// 處理後的驗證碼
        public Bitmap BinaryZaTion()
        {
            for (int x = 0; x < img.Width; x++)
            {
                for (int y = 0; y < img.Height; y++)
                {
                    __c = img.GetPixel(x, y);
                    //灰度值
                    int __tc = (__c.R + __c.G + __c.B) / 3;
                    //大於阙值 黑色
                    if (__tc > t)
                    {
                        img.SetPixel(x, y, Color.FromArgb(__c.A, b, b, b));
                        //黑色點個數自加
                        __blackNum++;
                    }
                    //大於阙值 白色
                    else
                    {
                        img.SetPixel(x, y, Color.FromArgb(__c.A, w, w, w));
                    }
                }
            }
            return img;
        }
        #endregion

二值化過後需要判斷圖片的黑白比列,若果黑色比白色多,需要對圖片反色處理。

代碼如下:

 #region 是否需要反色
        /// 
        /// 是否需要反色
        /// 
        /// 是否需要反色
        public bool IsNeedInverseColor()
        {
            if ((__blackNum * 1.0 / (img.Width * img.Height)) > 0.5)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion

        #region 反色
        /// 
        /// 反色
        /// 
        /// 處理後的驗證碼
        public Bitmap InverseColor()
        {
            for (int x = 0; x < img.Width; x++)
            {
                for (int y = 0; y < img.Height; y++)
                {
                    __c = img.GetPixel(x, y);
                    img.SetPixel(x, y, Color.FromArgb(__c.A, w - __c.R, w - __c.G, w - __c.B));
                }
            }
            return img;
        }
        #endregion

處理結果如下:

\

2.圖片分割<喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vc3Ryb25nPjwvcD4KPHA+ztK1xNf2t6jKx8/Iw7/Su8r60NDF0LbPyse38crHtL+w18mr0NCjrLK7yse1xLuwvMfCvLWxx7B41/ix6qOsyLu688O70tS64dDQxdC2z8rHt/G0v7DXyavQ0KOs1eLR+b7NxNy1xLW9w7/Su7j2yv3X1rXEx/jT8qOsyLu6872rx/jT8ruts/bAtKGjPC9wPgo8cD60+sLryOfPwqO6PC9wPgo8cD48L3A+CjxwcmUgY2xhc3M9"brush:java;"> #region 分割圖片 ///

/// 分割圖片 /// /// 處理後的驗證碼 public Bitmap CutImg() { //Y軸分割 CutY(); //區域個數 __count = 0; if (XList.Count > 1) { //x起始值 int __start = XList[0]; //x結束值 int __end = XList[XList.Count - 1]; //x索引 int __idx = 0; while (__start != __end) { //區域寬度 int __w = __start; //區域個數自加 __count++; while (XList.Contains(__w) && __idx < XList.Count) { //區域寬度自加 __w++; //x索引自加 __idx++; } //區域X軸坐標 int x = __start; //區域Y軸坐標 int y = 0; //區域寬度 int width = __w - __start; //區域高度 int height = img.Height; /* * X軸分割當前區域 */ CutX(img.Clone(new Rectangle(x, y, width, height), img.PixelFormat)); if (YList.Count > 1 && YList.Count != img.Height) { int y1 = YList[0]; int y2 = YList[YList.Count - 1]; if (y1 != 1) { y = y1 - 1; } height = y2 - y1 + 1; } //GDI+繪圖對象 Graphics g = Graphics.FromImage(img); g.SmoothingMode = SmoothingMode.HighQuality; g.CompositingMode = CompositingMode.SourceOver; g.PixelOffsetMode = PixelOffsetMode.HighSpeed; g.InterpolationMode = InterpolationMode.HighQualityBicubic; //畫出驗證碼區域 g.DrawRectangle(new Pen(Brushes.Green), new Rectangle(x, y, width, height)); g.Dispose(); //起始值指向下一組 if (__idx < XList.Count) { __start = XList[__idx]; } else { __start = __end; } } } return img; } #endregion #region Y軸字符分割圖片 /// /// 得到Y軸分割點 /// 判斷每一豎行是否有黑色 /// 有則添加 /// /// 要驗證的圖片 private void CutY() { XList.Clear(); for (int x = 0; x < img.Width; x++) { isWhilteLine = false; for (int y = 0; y < img.Height; y++) { __c = img.GetPixel(x, y); if (__c.R == w) { isWhilteLine = true; } else { isWhilteLine = false; break; } } if (!isWhilteLine) { XList.Add(x); } } } #endregion #region X軸字符分割圖片 /// /// 得到X軸分割點 /// 判斷每一橫行是否有黑色 /// 有則添加 /// /// 臨時區域 private void CutX(Bitmap tempImg) { YList.Clear(); for (int x = 0; x < tempImg.Height; x++) { isWhilteLine = false; for (int y = 0; y < tempImg.Width; y++) { __c = tempImg.GetPixel(y, x); if (__c.R == w) { isWhilteLine = true; } else { isWhilteLine = false; break; } } if (!isWhilteLine) { YList.Add(x); } } tempImg.Dispose(); } #endregion


效果如下:

\


3.識別

識別呢就是提取出圖片的特征

我的做法是將圖片數字區域逐一分成4*4的區域,計算出各個區域的黑色點所占的百分比,然後將計算出來的結果和以前計算的特征進行比較,求出歐氏距離 d = sqrt( (x1-x2)^2+(y1-y2)^2 )最小的一個作為結果。

部分代碼如下:

#region 黑色像素比列
        /// 
        /// 計算黑色像素比列
        /// 
        /// 
        /// 
        private double PixlPercent(Bitmap tempimg)
        {
            int temp = 0;
            int w_h = tempimg.Width * tempimg.Height;
            for (int x = 0; x < tempimg.Width; x++)
            {
                for (int y = 0; y < tempimg.Height; y++)
                {
                    __c = tempimg.GetPixel(x, y);
                    if (__c.R == b)
                    {
                        temp++;
                    }
                }
            }
            tempimg.Dispose();
            double result = temp * 1.0 / w_h;
            result = result.ToString().Length > 3 ? Convert.ToDouble(result.ToString().Substring(0, 3)) : result;
            return result;
        }
        #endregion


效果如下:



本代碼只做研究學習之用。

新手上路,有任何建議、意見聯系 [email protected]


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved