CMCC-EDU 模擬登陸中的驗證碼識別

文章地址:http://blog.csdn.net/u011535382/article/details/48210643

      本文是成都地區CMCC-EDU登陸時候的驗證碼識別過程分析,完整的登陸過程分析在 這裏

1.驗證碼識別難度分析

      經過對比觀察發現,CMCC-EUD的驗證碼其實很二的大笑,其中每個數字的出現位置是固定的,每個數字每次出現的形狀也是一樣的,只有少量的噪點可以通過分區和二值化處理來消除。


    可以將圖片看成是44*20的一個矩陣,只要能夠把它每個數字標準的形式存儲下來,再將整個驗證碼分爲四個區域,逐一比較,找出差異度最小的就實現了。

2.標準數字矩陣的建立

    由於每個數字可以看成是 13*9 的矩陣,需要將他們轉化爲二值並儲存在二維數組中作爲每次比較的標準。先通過ps將圖片裁剪成 13*9 分辨率的文件,再由軟件對比識別。

這是二值化前的效果:


    其中彩色轉化爲灰度的計算方式爲 gray = R*0.11+G *0.59 + B*0.3;灰度轉二值的閥值取爲 128,這樣實際的的效果最好。再將識別出來的圖像矩陣存儲到文本文件 stand.txt 中方便以後編程的使用。

 二值化後的效果:


4.驗證碼的識別思路

1、將待驗證的圖片分爲四個區域;

2、選擇一個區域數字識別;

3、將10個標準數字矩陣和待識別區做異或操作,統計差異最小的那個數就是識別出來的數num;

4、若四個區域都識別完,返回識別結果,若沒有,轉到步驟2。

5.具體實現代碼

/*
驗證碼識別函數
參數: 包含驗證碼圖片的 CImage 對象
返回值: 識別結果的 CString */
CString Distinguish(CImage &image)
{
    CString strResult;
    //每張驗證碼分爲四個區域
    for(int temp= 0; temp<=3; temp++)
    {
        bool pixelArray[13][9] = {0};
        int numL = 11*temp+2;   //x像素座標的左邊起點
        int numR = numL + 9;  //x像素座標的右邊起點
        int resultNum = 0;
        //對一個圖像進行掃描二值化 存儲在  pixelArray
        for (int y=2; y<15; y++)
        {
            for (int x=numL; x<numR; x++)
            {
                COLORREF colorRef = image.GetPixel(x,y);
                //RGB同時擴大100倍  轉化爲灰度值
                int gray = GetRValue(colorRef)*11+GetGValue(colorRef)*59+GetBValue(colorRef)*30;
                if (gray>=12800)
                {
                    pixelArray[y-2][x-numL] = true;
                }
                else
                {
                    pixelArray[y-2][x-numL] = false;
                }
            }
        }

        //對一個區域的數字進行識別
        //將10個標準數字與目標數字矩陣比較
        int mincount = 117;
        for (int num =0; num<10; num++)
        {
            int count = 0;
            for (int y=0; y<13; y++)
            {
                for (int x=0; x<9 ;x++)
                {
                    //統計差異的個數
                    if (standNum[num][y][x]&&pixelArray[y][x])
                    {
                        count++;
                    }
                }
            }

            if (count<mincount)
            {
                mincount = count;
                resultNum = num;
            }
        }
        //將識別出來的數字轉化爲CString
        CString strFormat;
        strFormat.Format("%d", resultNum);
        strResult += strFormat;
    }

    return strResult;
}

6.驗證碼識別效果

  經過300多張圖片的測試,成功率爲 100% (主要是圖片太簡單)。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章