最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用C#的aforge類庫識別驗證碼實例

 更新時間:2014年08月18日 11:51:08   投稿:junjie  
這篇文章主要介紹了使用C#的aforge類庫識別驗證碼實例,aforge類庫是一個非常強大的類庫,包括計算機視覺與人工智能、圖像處理、神經(jīng)網(wǎng)絡、遺傳算法、機器學習、機器人等領域,需要的朋友可以參考下

時間過得真快啊,轉(zhuǎn)眼今年就要過去了,大半年都沒有寫博客了,要說時間嘛,花在泡妹子和搞英語去了,哈哈。。。前幾天老大問我

怎么這么長時間都沒寫博客了,好吧,繼續(xù)堅持,繼續(xù)分享我的心得體會。

  這個系列我們玩玩aforge.net,套用官方都話就是一個專門為開發(fā)者和研究者基于C#框架設計的,這個框架提供了不同的類庫和關于類庫的

資源,還有很多應用程序例子,包括計算機視覺與人工智能,圖像處理,神經(jīng)網(wǎng)絡,遺傳算法,機器學習,機器人等領域,這個系列研究的重點

就是瞎幾把搞下AForge.Imaging這個命名空間下面的東東,下載網(wǎng)址:http://www.aforgenet.com/framework/downloads.html

    對了,不知道有多少公司是用得仕卡作為員工的福利卡,我們公司就是這樣的,每個月公司都會充值一些money,然后我們這些屁碼農(nóng)每個月15號就都開心的去看看發(fā)了多少。

上去看了后,喲呵~ 還有個90年代的驗證碼,我想這年頭估計找到這樣驗證碼的網(wǎng)站已經(jīng)不多了,如果懂一點圖像處理都話,這張驗證碼

跟沒有一個樣,謝謝。。。這篇我們看看怎么去識別它。

一: 驗證碼處理

1.  一般處理原則

    這種驗證碼為什么說跟沒有一樣,第一點:字體規(guī)范工整,第二點:不旋轉(zhuǎn)扭曲粘連,第三點:字體顏色單一,下面看處理步驟。

這里要注意的是,aforge只接受像素格式為24/32bpp的像素格式圖片,所以處理前,先進行格式轉(zhuǎn)化。

復制代碼 代碼如下:

//轉(zhuǎn)化圖片像素格式
            var bnew = new Bitmap(b.Width, b.Height, PixelFormat.Format24bppRgb);

            Graphics g = Graphics.FromImage(bnew);

            g.DrawImage(b, 0, 0);

            g.Dispose();

<1>圖片灰度化

這是圖像識別通常都要走的第一步,圖片灰度化有助于減少后續(xù)對rgb的計算量,同時也方便我們進行二值化,在aforge中我們有專門的類一步搞定,簡潔方便。

復制代碼 代碼如下:

            //灰度化
            b = new Grayscale(0.2125, 0.7154, 0.0721).Apply(b);

<2>二值化

  二值化顧名思義就是二種值,比如非白即黑,非黑即白,那么白和黑的標準就需要提供一個閾值,大于或者小于怎么樣,在aforge同樣也有相似的類進行處理

復制代碼 代碼如下:

            //二值化
            b = new Threshold(50).Apply(b);

<3> 去噪點

  從上面的圖片可以發(fā)現(xiàn)有很多紅點點,搞得像皮膚病一樣,仔細觀察可以看到這種噪點具有獨立,體積小的特征,所以判斷的標準就是如果圖中某個區(qū)塊的大小在我設置的閾值內(nèi),就將其去掉,同樣也有專門的類進行處理。

復制代碼 代碼如下:

            //去噪點
            new BlobsFiltering(1, 1, b.Width, b.Height).Apply(b);

  這里具體怎么傳遞參數(shù),后續(xù)系列會慢慢解讀。

<4>切割圖片

   切圖片的好處在于我們需要知道真正要識別的元素的有效范圍是多大,同時也方便我們將這些圖片作為模板保存下來。

代碼如下:

復制代碼 代碼如下:

/// <summary>
        /// 按照 Y 軸線 切割
        /// (丟棄等于號)
        /// </summary>
        /// <param name="?"></param>
        /// <returns></returns>
        public List<Bitmap> Crop_Y(Bitmap b)
        {
            var list = new List<Bitmap>();

            //統(tǒng)計每一列的“1”的個數(shù),方便切除
            int[] cols = new int[b.Width];

            /*
             *  縱向切割
             */
            for (int x = 0; x < b.Width; x++)
            {
                for (int y = 0; y < b.Height; y++)
                {
                    //獲取當前像素點像素
                    var pixel = b.GetPixel(x, y);

                    //說明是黑色點
                    if (pixel.R == 0)
                    {
                        cols[x] = ++cols[x];
                    }
                }
            }

            int left = 0, right = 0;

            for (int i = 0; i < cols.Length; i++)
            {
                //說明該列有像素值(為了防止像素干擾,去噪后出現(xiàn)空白的問題,所以多判斷一下,防止切割成多個)
                if (cols[i] > 0 || (i + 1 < cols.Length && cols[i + 1] > 0))
                {
                    if (left == 0)
                    {
                        //切下來圖片的橫坐標left
                        left = i;
                    }
                    else
                    {
                        //切下來圖片的橫坐標right
                        right = i;
                    }
                }
                else
                {
                    //說明已經(jīng)有切割圖了,下面我們進行切割處理
                    if ((left > 0 || right > 0))
                    {
                        Crop corp = new Crop(new Rectangle(left, 0, right - left + 1, b.Height));

                        var small = corp.Apply(b);

                        //居中,將圖片放在20*50的像素里面

                        list.Add(small);
                    }

                    left = right = 0;
                }
            }

            return list;
        }

        /// <summary>
        /// 按照 X 軸線 切割
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        public List<Bitmap> Crop_X(List<Bitmap> list)
        {
            var corplist = new List<Bitmap>();

            //再對分割的圖進行上下切割,取出上下的白邊
            foreach (var segb in list)
            {
                //統(tǒng)計每一行的“1”的個數(shù),方便切除
                int[] rows = new int[segb.Height];

                /*
                 *  橫向切割
                 */
                for (int y = 0; y < segb.Height; y++)
                {
                    for (int x = 0; x < segb.Width; x++)
                    {
                        //獲取當前像素點像素
                        var pixel = segb.GetPixel(x, y);

                        //說明是黑色點
                        if (pixel.R == 0)
                        {
                            rows[y] = ++rows[y];
                        }
                    }
                }

                int bottom = 0, top = 0;

                for (int y = 0; y < rows.Length; y++)
                {
                    //說明該行有像素值(為了防止像素干擾,去噪后出現(xiàn)空白的問題,所以多判斷一下,防止切割成多個)
                    if (rows[y] > 0 || (y + 1 < rows.Length && rows[y + 1] > 0))
                    {
                        if (top == 0)
                        {
                            //切下來圖片的top坐標
                            top = y;
                        }
                        else
                        {
                            //切下來圖片的bottom坐標
                            bottom = y;
                        }
                    }
                    else
                    {
                        //說明已經(jīng)有切割圖了,下面我們進行切割處理
                        if ((top > 0 || bottom > 0) && bottom - top > 0)
                        {
                            Crop corp = new Crop(new Rectangle(0, top, segb.Width, bottom - top + 1));

                            var small = corp.Apply(segb);

                            corplist.Add(small);
                        }

                        top = bottom = 0;
                    }
                }
            }

            return corplist;
        }

<5> 圖片精處理

  這里要注意的是,比如數(shù)字“2”,切除上下左右的空白后,再加上噪點的干擾,不一定每次切下來的圖片大小都一樣,所以這里為了方便更好的識別,我們需要重置下圖片的大小,并且將“數(shù)字2”進行文字居中。

復制代碼 代碼如下:

/// <summary>
        /// 重置圖片的指定大小并且居中
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public List<Bitmap> ToResizeAndCenterIt(List<Bitmap> list, int w = 20, int h = 20)
        {
            List<Bitmap> resizeList = new List<Bitmap>();


            for (int i = 0; i < list.Count; i++)
            {
                //反轉(zhuǎn)一下圖片
                list[i] = new Invert().Apply(list[i]);

                int sw = list[i].Width;
                int sh = list[i].Height;

                Crop corpFilter = new Crop(new Rectangle(0, 0, w, h));

                list[i] = corpFilter.Apply(list[i]);

                //再反轉(zhuǎn)回去
                list[i] = new Invert().Apply(list[i]);

                //計算中心位置
                int centerX = (w - sw) / 2;
                int centerY = (h - sh) / 2;

                list[i] = new CanvasMove(new IntPoint(centerX, centerY), Color.White).Apply(list[i]);

                resizeList.Add(list[i]);
            }

            return resizeList;
        }

其實精處理后,這些圖片就可以作為我們的模板庫的圖片了,可以將每張模板圖都標記下具體的數(shù)字,后續(xù)我們再遇到時,計算下其相似度就可以了,下面就是已經(jīng)制作好的模板。

<6> 模板匹配識別

  既然模板圖片都制作好了,一切都差不多水到渠成了,下次來的驗證碼我都切好后做成精圖片后跟模板進行匹配,在afroge里面

有一個ExhaustiveTemplateMatching,專門用來進行模板匹配用的,很方便。

復制代碼 代碼如下:

 ExhaustiveTemplateMatching templateMatching = new ExhaustiveTemplateMatching(0.9f);

這里的0.9f就是設定的閾值,只有大于0.9的閾值,我才認為該模板與目標圖片相似,然后在所有大于0.9的相似度中取到最大的一個作為

我們最后識別的圖像。

復制代碼 代碼如下:

var files = Directory.GetFiles(Environment.CurrentDirectory + "\\Template\\");

            var templateList = files.Select(i => { return new Bitmap(i); }).ToList();
            var templateListFileName = files.Select(i => { return i.Substring(30, 1); }).ToList();

            var result = new List<string>();

            ExhaustiveTemplateMatching templateMatching = new ExhaustiveTemplateMatching(0.9f);

            //這里面有四張圖片,進行四張圖的模板匹配
            for (int i = 0; i < list.Count; i++)
            {
                float max = 0;
                int index = 0;

                for (int j = 0; j < templateList.Count; j++)
                {
                    var compare = templateMatching.ProcessImage(list[i], templateList[j]);

                    if (compare.Length > 0 && compare[0].Similarity > max)
                    {
                        //記錄下最相似的
                        max = compare[0].Similarity;
                        index = j;
                    }
                }

                result.Add(templateListFileName[index]);
            }

最后的效果還是不錯的,識別率基本100%吧。

相關文章

  • C#打印日志的方法總結(jié)

    C#打印日志的方法總結(jié)

    在本篇文章里小編給大家整理了關于C#如何打印日志的技巧總結(jié),需要的朋友們跟著學習下。
    2019-03-03
  • C#對二進制數(shù)據(jù)進行base64編碼的方法

    C#對二進制數(shù)據(jù)進行base64編碼的方法

    這篇文章主要介紹了C#對二進制數(shù)據(jù)進行base64編碼的方法,涉及C#中Convert.ToBase64String用法技巧,需要的朋友可以參考下
    2015-04-04
  • WPF中圖像處理的方法介紹

    WPF中圖像處理的方法介紹

    這篇文章介紹了WPF中圖像處理的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • c# winform多線程死循環(huán)踩坑

    c# winform多線程死循環(huán)踩坑

    本文主要介紹了c# winform多線程死循環(huán)踩坑,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-12-12
  • 使用C#快速搭建一個在windows運行的exe應用

    使用C#快速搭建一個在windows運行的exe應用

    這篇文章主要介紹了使用C#快速搭建一個在windows運行的exe應用,這是一個比較舊的內(nèi)容,但是一直都沒有空寫,今天花點時間,把我掌握的C# 分享給初學的人或者感興趣的人,希望能對你有一定幫助,感興趣的小伙伴跟著小編一起來看看吧
    2024-07-07
  • C#實現(xiàn)實體類和XML相互轉(zhuǎn)換

    C#實現(xiàn)實體類和XML相互轉(zhuǎn)換

    這篇文章主要為大家詳細介紹了C#實現(xiàn)實體類和XML相互轉(zhuǎn)換的資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • C# 數(shù)組實例介紹(圖文)

    C# 數(shù)組實例介紹(圖文)

    數(shù)組即是一組相同類型組合在一起,使用一個通用的名稱,通過分配的下標訪問的數(shù)據(jù)集合中的元素。
    2014-08-08
  • C#登入實例

    C#登入實例

    本篇文章通過截圖的方式向大家展示C#程序登陸實現(xiàn)的全過程,利用了C#三層架構(gòu)的編寫方法,希望對大家今后編寫代碼有所幫助
    2016-11-11
  • C#操作文件和注冊表的示例詳解

    C#操作文件和注冊表的示例詳解

    這篇文章主要為大家詳細介紹了C#中操作文件和注冊表的相關知識,文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以參考下
    2024-03-03
  • VS2015 C#生成dll文件的方法(32/64)

    VS2015 C#生成dll文件的方法(32/64)

    這篇文章主要介紹了VS2015 C#生成dll文件的方法(32/64),需要的朋友可以參考下
    2016-12-12

最新評論

横山县| 镇江市| 察雅县| 大方县| 扎兰屯市| 弥渡县| 东阳市| 杭锦旗| 白河县| 梓潼县| 同江市| 江油市| 海盐县| 龙胜| 洱源县| 蚌埠市| 普格县| 台南县| 开原市| 温泉县| 永年县| 峨边| 澜沧| 呼和浩特市| 新津县| 邹平县| 新安县| 渝中区| 洛隆县| 老河口市| 梅河口市| 本溪| 临朐县| 中宁县| 上虞市| 上饶市| 沭阳县| 新干县| 天气| 黄石市| 昌平区|