在別論壇看到的 希望對做插件大大有幫助 我也不太懂
雖然不是所有驗證碼都能識別(如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";
六、完成驗證碼圖片的識別
將獲取的特徵碼和對應的數字或字符保存起來,下次再將新獲取的特徵碼跟保存的特徵碼對比,如果相同則提取對應的數字或字符,完成驗證碼的識別。
雖然不是所有驗證碼都能識別(如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";
六、完成驗證碼圖片的識別
將獲取的特徵碼和對應的數字或字符保存起來,下次再將新獲取的特徵碼跟保存的特徵碼對比,如果相同則提取對應的數字或字符,完成驗證碼的識別。