1. 程式人生 > >Python指令碼破解圖形驗證碼(tesserocr和pytesseract)

Python指令碼破解圖形驗證碼(tesserocr和pytesseract)

在學習之前,我們先了解OCR、tesseract、tesserocr、pytesseract和opencv這幾個跟圖片處理有關的庫。

OCR(Optical Character Recognition)光學字元識別,是指通過掃描字元,然後通過其形狀將其翻譯成電子文字的過程。

tesseract是一個OCR,在Windows、Linux和Mac OS下均可安裝。

tesserocr 和 pytesseract 是對tesseract封裝的一個Python庫,可以用來識別圖片中的字元。pytesseract是Google的Tesseract-OCR引擎包裝器。所以在使用tesserocr和pytesseract之前,我們需要安裝tesseract。至於怎麼安裝我就不說了,網上一搜一大把。

opencv是一個基於BSD許可(開源)發行的跨平臺計算機視覺庫,也可以用於圖片處理。

既然是破解圖形驗證碼,我們就得先了解一下圖片的有關知識。

絕大部分圖片是 RGB 型別的,即是用RGB(紅綠藍)三原色組成的圖片。在影象處理中,用RGB三個分量(R:Red,G:Green,B:Blue),即紅、綠、藍三原色來表示真彩色,R分量,G分量,B分量的取值範圍均為0~255,比如電腦螢幕上的一個紅色的畫素點的三個分量的值分別為:255,0,0

畫素點

我們的圖片是由一個一個的畫素點組成的,畫素是影象的最小單元,我們右鍵——>屬性去檢視圖片的資訊,看到圖片的尺寸1024*1024

即寬度是1024個畫素,高度也是1024個畫素,也就是說這張圖片是由一個1024 * 1024的畫素點矩陣構成的,這個矩陣是1024行,1024列,共有1024 * 1024 = 1048576個畫素點。

因為一個畫素點的顏色是由RGB三個值來表現的,所以一個畫素點矩陣對應三個顏色向量矩陣,分別是R矩陣,G矩陣,B矩陣,它們也都是1024 *1024大小的矩陣。我們可以理解為這張圖片是由3個1024*1024的矩陣重和起來的,才形成了這張圖片最後的效果。

如下:

這個是R矩陣中的一部分
影象處理的灰度化和二值化

這個是G矩陣中的一部分
影象處理的灰度化和二值化

這個是B矩陣中的一部分

影象處理的灰度化和二值化
比如每個矩陣的第一行第一列的值分別為:R:240,G:223,B:204,所以這個畫素點的顏色就是(240,223,204)。如果圖片某個地方顯示的是紅色,那麼這個地方的畫素值就是:R:255  G:0 B:0   (255,0,0) 。

圖片的灰度化

在理解了一張圖片是由一個畫素點矩陣構成之後,我們就知道我們對影象的處理就是對這個畫素點矩陣的操作,想要改變某個畫素點的顏色,我們只要在這個畫素點矩陣中找到這個畫素點的位置,比如第x行,第y列,所以這個畫素點在這個畫素點矩陣中的位置就可以表示成(x,y),因為一個畫素點的顏色由紅、綠、藍三個顏色變量表示,所以我們通過給這三個變數賦值,來改變這個畫素點的顏色,比如改成紅色(255,0,0),可以表示為(x,y,(R=255,G=0,B=0))x行y列的畫素值為(255,0,0)。

      那麼什麼叫圖片的灰度化呢?其實很簡單,就是讓畫素點矩陣中的每一個畫素點都滿足下面的關係:R=G=B(就是紅色變數的值,綠色變數的值,和藍色變數的值,這三個值相等),此時的這個值叫做灰度值。

一般灰度處理經常使用下面幾種方法來進行處理。

方法1 平均值法:

  • 灰度化後的R=(處理前的R + 處理前的G +處理前的B)/ 3
  • 灰度化後的G=(處理前的R + 處理前的G +處理前的B)/ 3
  • 灰度化後的B=(處理前的R + 處理前的G +處理前的B)/ 3

方法2 加權平均法(處理效果最好):

  • 灰度化後的R =  處理前的R * 0.3+ 處理前的G * 0.59 +處理前的B * 0.11
  • 灰度化後的G =  處理前的R * 0.3+ 處理前的G * 0.59 +處理前的B * 0.11
  • 灰度化後的B =  處理前的R * 0.3+ 處理前的G * 0.59 +處理前的B * 0.11

方法3 最大值發:

   灰度化後的R、G、B=處理前的R、G、B中的最大值

https://blog.csdn.net/L0_o_0f/article/details/80180111

如下是利用python將圖片進行灰度化處理後的效果,直接利用的PIL庫Image類的方法(應該用的是方法2來進行灰度化)

from PIL import Image
img=Image.open("1.jpg")
img.convert("L").show()  #將圖片進行灰度化處理並且顯示

圖片的二值化

什麼叫影象的二值化?二值化就是讓影象的畫素點矩陣中的每個畫素點的灰度值為0(黑色)或者255(白色),也就是讓整個影象呈現只有黑和白的效果。在灰度化的影象中灰度值的範圍為0~255,在二值化後的影象中的灰度值範圍是0或者255。

  • 黑色:二值化後的R = 二值化後的G = 二值化後的B =  0
  • 白色:二值化後的R = 二值化後的G = 二值化後的B =  255

那麼一個畫素點在灰度化之後的灰度值怎麼轉化為 0 或者255呢?比如灰度值為120,那麼在二值化後到底是0還是255?

這就涉及到取一個閥值的問題。

常用的二值化方法:

方法1:

          取閥值為127(相當於0~255的中數),讓灰度值小於等於127的變為0(黑色),灰度值大於127的變為255(白色),這樣做的好處是計算量小速度快,但是缺點也是很明顯的,因為這個閥值在不同的圖片中均為127。但是不同的圖片,他們的顏色 分佈差別很大,所以用127做閥值,效果肯定是不好的。

方法2:

          取閥值為計算畫素點矩陣中的所有畫素點的灰度值的平均值

        (畫素點1灰度值+...+畫素點n灰度值)/ n = 畫素點平均值avg

         然後讓每一個畫素點與畫素點平均值比較,小於等於avg的畫素點就為0(黑色),大於avg的 為255(白色)

方法3:

          使用直方圖方法(也叫雙峰法)來尋找閥值,直方圖是影象的重要特質。直方圖方法認為影象由前景和背景組成,在灰度直方圖上,前景和背景都形成高峰,在雙峰之間的最低谷處就是閥值所在。取到閥值之後再一 一比較就可以了。

# 圖片二值化
from PIL import Image
img = Image.open('1.jpg')
Img = img.convert('L')   #灰度化處理
Img.save("test1.jpg")   #將灰度化圖片儲存為test1.jpg
 
threshold = 127           #我們自己定義的閾值
table = []
for i in range(256):
    if i < threshold:
        table.append(0)
    else:
        table.append(1)
# 圖片二值化
photo = Img.point(table, '1')
photo.save("test2.jpg")  #得到二值化處理後圖片test2.jpg
Image.open("test2.jpg").show()   #顯示二值化處理後的圖片