python驗證碼識別的範例程式碼,python範例程式碼

來源:互聯網
上載者:User

python驗證碼識別的範例程式碼,python範例程式碼

寫爬蟲有一個繞不過去的問題就是驗證碼,現在驗證碼分類大概有4種:

  • 映像類
  • 滑動類
  • 點擊類
  • 語音類

今天先來看看映像類,這類驗證碼大多是數字、字母的組合,國內也有使用漢字的。在這個基礎上增加噪點、幹擾線、變形、重疊、不同字型顏色等方法來增加識別難度。

相應的,驗證碼識別大體可以分為下面幾個步驟:

  • 灰階處理
  • 增加對比(可選)
  • 二值化
  • 降噪
  • 傾斜校正分割字元
  • 建立訓練庫
  • 識別

由於是實驗性質的,文中用到的驗證碼均為程式產生而不是批量下載真實的網站驗證碼,這樣做的好處就是可以有大量的知道明確結果的資料集。

當需要真實環境下需要擷取資料時,可以使用結合各個大碼平台來建立資料集進行訓練。

產生驗證碼這裡我使用Claptcha這個庫,當然Captcha這個庫也是個不錯的選擇。

為了產生最簡單的純數字、無幹擾的驗證碼,首先需要將claptcha.py的285行_drawLine做一些修改,我直接讓這個函數返回None,然後開始產生驗證碼:

from claptcha import Claptchac = Claptcha("8069","/usr/share/fonts/truetype/freefont/FreeMono.ttf")t,_ = c.write('1.png')

這裡需要注意ubuntu的字型路徑,也可以在網上下載其他字型使用。產生驗證碼如下:

 

可以看出,驗證碼有形變。對於這類最簡單的驗證碼,可以直接使用Google開源的tesserocr來識別。

首先安裝:

apt-get install tesseract-ocr libtesseract-dev libleptonica-devpip install tesserocr

然後開始識別:

from PIL import Imageimport tesserocrp1 = Image.open('1.png')tesserocr.image_to_text(p1)'8069\n\n'

可以看出,對於這種簡單的驗證碼,基本什麼都不做識別率就已經很高了。有興趣的小夥伴可以用更多的資料來測試,這裡我就不展開了。

接下來,在驗證碼背景添加噪點來看看:

c = Claptcha("8069","/usr/share/fonts/truetype/freefont/FreeMono.ttf",noise=0.4)t,_ = c.write('2.png')

產生驗證碼如下:

 

識別:

p2 = Image.open('2.png')tesserocr.image_to_text(p2)'8069\n\n'

效果還可以。接下來產生一個字母數字組合的:

c2 = Claptcha("A4oO0zZ2","/usr/share/fonts/truetype/freefont/FreeMono.ttf")t,_ = c2.write('3.png')

產生驗證碼如下:

 

第3個為小寫字母o,第4個為大寫字母O,第5個為數字0,第6個為小寫字母z,第7個為大寫字母Z,最後一個是數字2。人眼已經跪了有木有!但現在一般驗證碼對大小寫是不做嚴格區分的,看自動識別什麼樣吧:

p3 = Image.open('3.png')tesserocr.image_to_text(p3)'AMOOZW\n\n'

人眼都跪的電腦當然也廢了。但是,對於一些幹擾小、形變不嚴重的,使用tesserocr還是十分簡單方便的。然後將修改的claptcha.py的285行_drawLine還原,看添加幹擾線的情況。

 

p4 = Image.open('4.png')tesserocr.image_to_text(p4)

加了條幹擾線就完全識別不出來了,那麼有沒有什麼辦法去除幹擾線呢?

雖然圖片看上去是黑白的,但還需要進行灰階處理,否則使用load()函數得到的是某個像素點的RGB元組而不是單一值了。處理如下:

def binarizing(img,threshold): """傳入image對象進行灰階、二值處理""" img = img.convert("L") # 轉灰階 pixdata = img.load() w, h = img.size # 遍曆所有像素,大於閾值的為黑色 for y in range(h):  for x in range(w):   if pixdata[x, y] < threshold:    pixdata[x, y] = 0   else:    pixdata[x, y] = 255 return img

處理後的圖片如下:

 

可以看出處理後圖片銳利化了很多,接下來嘗試去除幹擾線,常見的4鄰域、8鄰域演算法。所謂的X鄰域演算法,可以參考手機九宮格IME,按鍵5為要判斷的像素點,4鄰域就是判斷上下左右,8鄰域就是判斷周圍8個像素點。如果這4或8個點中255的個數大於某個閾值則判斷這個點為噪音,閾值可以根據實際情況修改。

def depoint(img): """傳入二值化後的圖片進行降噪""" pixdata = img.load() w,h = img.size for y in range(1,h-1):  for x in range(1,w-1):   count = 0   if pixdata[x,y-1] > 245:#上    count = count + 1   if pixdata[x,y+1] > 245:#下    count = count + 1   if pixdata[x-1,y] > 245:#左    count = count + 1   if pixdata[x+1,y] > 245:#右    count = count + 1   if pixdata[x-1,y-1] > 245:#左上    count = count + 1   if pixdata[x-1,y+1] > 245:#左下    count = count + 1   if pixdata[x+1,y-1] > 245:#右上    count = count + 1   if pixdata[x+1,y+1] > 245:#右下    count = count + 1   if count > 4:    pixdata[x,y] = 255 return img

處理後的圖片如下:

 

好像……根本沒卵用啊?!確實是這樣的,因為樣本中的圖片幹擾線的寬度和數字是一樣的。對於幹擾線和資料像素不同的,比如Captcha產生的驗證碼:

 

從左至右依次是原圖、二值化、去除幹擾線的情況,總體降噪的效果還是比較明顯的。另外降噪可以多次執行,比如我對上面的降噪後結果再進行依次降噪,可以得到下面的效果:

 

再進行識別得到了結果:

p7 = Image.open('7.png')tesserocr.image_to_text(p7)'8069 ,,\n\n'

另外,從圖片來看,實際資料顏色明顯和噪點幹擾線不同,根據這一點可以直接把噪點全部去除,這裡就不展開說了。

第一篇文章,先記錄如何將圖片進行灰階處理、二值化、降噪,並結合tesserocr來識別簡單的驗證碼,剩下的部分在下一篇文章中和大家一起分享。

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援幫客之家。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.