[轉貼]驗證碼識別的基本思路及方法

来源:互联网 发布:网络男女对唱好听歌曲 编辑:程序博客网 时间:2024/06/17 11:25

 

在別論壇看到的 希望對做插件大大有幫助 我也不太懂

雖然不是所有驗證碼都能識別(如QQ的變形漢字驗證碼是不太可能用軟體識別的,個人覺得),但還是有很多驗證碼可以用軟體來識別的。

下面以天涯博客裡的評論驗證碼為例,說明驗證碼識別的基本思路和方法:

                  (網頁截圖)

第一步、獲取驗證碼圖片
C#可以用HttpWebRequest類GET驗證碼的網址,得到返回的資料流,再將資料流值賦給Bitmap變量。在Winform裡放一個PictureBox控件,將它的Image屬性指定為Bitmap變量,就可以顯示出驗證碼圖片了。
也可以使用Bitmap的Save方法將圖片保存成Bmp檔案。
    Stream resStream = response.GetResponseStream();//得到驗證碼資料流
    Bitmap sourcebm = new Bitmap(resStream);//初始化Bitmap圖片
在Photoshop中將驗證碼圖片放大1600%,如下:


第二步、將驗證碼圖片去色(將彩色轉換為灰度)
去色是為了進一步做成黑白雙色圖片。
    Color c = sourcebm.GetPixel(x、y);
    int luma = (int)(c.R * 0.3 + c.G * 0.59 + c.B * 0.11);//轉換灰度的算法
    sourcebm.SetPixel(x、y、Color.FromArgb(luma、luma、luma));


第三步、去雜色,轉換為黑白圖片
從灰度圖片中可以看出,數字的顏色比較深,而雜色都是比較淺,所以可以設定一個臨界顏色值,顏色高於或等於這個值的設置為白色,低於這個值的設置為黑色。
    Color c = sourcebm.GetPixel(x、y);
    if (c.R >= critical_value)
        sourcebm.SetPixel(x、y、Color.FromArgb(255、255、255));
    else
        sourcebm.SetPixel(x、y、Color.FromArgb(0、0、0));


第四步、動態得到每個數字的邊界


for (int x = 0; x < sourcebm.Width; x++)
{
    myColumn = true;
    for (int y = 0; y < sourcebm.Height; y++)
    {
        Color c = sourcebm.GetPixel(x、y);
        if (c.R == 0 && charStart == false)//第一次出現黑點
        {
            widthStartX[charNum] = x;
            charStart = true;
            break;
        }
        if (c.R == 0 && charStart == true)//後續出現黑點
        {
            myColumn = false;
            break;
        }
    }
    if (myColumn == true && charStart == true && widthStartX[charNum] < x)//如果當列沒有黑點並且前面出現過黑點還沒結束
    {
        widthEndX[charNum] = x - 1;
        charStart = false;
        charNum++;
    }
    if (charStart == true && myColumn == false && x == (bmp.Width - 1))//如果開始出現黑點了,並且最後一列也有黑點
    {
        widthEndX[charNum] = x;
        charStart = false;
        charNum++;
    }
}

五、得到每個字符的特徵碼
在每個字符的邊界內,檢測每個像素,如果象素為白色則為「0」,如果象素為黑色則為「1」,將「0」「1」連起來就是該數字或字符的特徵碼。
    Color c = sourcebm.GetPixel(x、y);
    if (c.R == 0)
        str = str + "1";
    else
        str = str + "0";

六、完成驗證碼圖片的識別
將獲取的特徵碼和對應的數字或字符保存起來,下次再將新獲取的特徵碼跟保存的特徵碼對比,如果相同則提取對應的數字或字符,完成驗證碼的識別。