前情提要
如圖所示
本來是非常簡單的一個驗證碼
使用pytesseract 識別失敗
使用libsvm識別失敗
使用tensflow識別成功
以上識別不成功不是因爲庫不好用,而是因爲水平太低
正文
1. 環境
- windows,python版本3.7.0
- 在anconda中,python版本3.5.3
2. pytesseract識別失敗過程
- 首先下載安裝tesseract.exe文件,附上tesseract各種語言訓練數據下載地址
- 在cmd中執行
pip install pytesseract
和pip install pillow
- 將test.png文件和python文件放在同一目錄下測試,python文件內容
import pytesseract
from PIL import Image
print(pytesseract.image_to_string(Image.open('test.png')))
結果爲空(= =!)
通過一番查詢,才知道原來下載下來的驗證碼圖片還需要進行進一步的處理,比如說二值化,去除噪點等操作,後來百度到字符型圖片驗證碼識別完整過程及Python實現這篇文章,跟着教程來處理圖片
- 二值化圖片
#name:當前目錄圖片名稱或絕對路徑(這是最簡單的二值化方法,還有更好的算法)
def get_bin_pic(name, threshold = 140):
table = []
for i in range(256);
if i < threshold:
table.append(0)
else:
table.append(1)
Img = Image.open(name)
Img = Img.convert("L")
Img = Img.point(table, "1")
Img.save(name) #覆蓋原圖片
get_bin_pic("test.png")
結果如圖所示,可以看出噪點很多
- 降噪 參考文章:完整的圖片去噪代碼(python)
結果如圖所示
這樣就得到了一張比較乾淨的圖片。經過這些處理再次調用最初的識別程序,結果依然爲空。
tesseract還可以自己訓練數據,簡單的訓練了一下,結果還是失敗,這裏就不講了。
3. libsvm識別失敗過程
既然tesseract識別失敗,那麼就轉到libsvm上來,字符型圖片驗證碼識別完整過程及Python實現這篇文章,講的很詳細,開頭部分有源碼,於是我把源碼下載下來,準備測試一番。
- 準備工作:需要對圖片進行切割,然後將圖片放到[0-Z]等36個文件夾中。
- 圖片切割代碼
因爲只有一個字符要切割,切位置固定,所以代碼很簡單。
from PIL import Image
import os
![def cut_img(name):
img = Image.open(name)
x = 6
y = 5
child_img = img.crop((x, y, x+15, y+15))
child_img.save(name)
將D:/pic
文件夾下的所有圖片都切割
for root, dirs, files in os.walk("D:/pic"):
for name in files:
cut_img(name)
結果
- 然後手動將所有的切圖手動放到[0-Z]的文件夾中,開始運行代碼,經過代碼的一番學習,運行結果識別率0%
出現這個原因我推測是因爲數據的原因,畢竟文章的博主可以達到幾乎100%的識別率,所以說只有可能是因爲我的驗證碼數據量太少。
爲了解決數據的問題,繼續搜索。
3. tensorflow識別成功
15 分鐘用 ML 破解一個驗證碼系統這篇文章中也提供了機器學習的源代碼,
做了一番測試,發現可以識別自己的部分驗證碼,但是識別成功率還是不高,於是開始自己將之前保存的[0-Z]文件夾中的圖片隨機選取4個,然後拼接在一起,做成1w條數據,
拼接代碼寫的很爛
from PIL import Image
import os
import time
import os,sys
import random
def appendFile(fileDir):
pathDir = os.listdir(fileDir)
for i in pathDir:
all.append(fileDir + "/" + i)
def getpic():
path = "E:/svm/pic3"
dirs = os.listdir(path)
i = 0
for child_dirs in dirs:
i = i + 1
appendFile(path + "/" + child_dirs)
sample = random.sample(all, 4)
result = Image.new("RGB",(72, 24),color="#FFFFFF")
left = 0
right = 15
name = ""
for i in sample:
a = Image.open(i)
result.paste(a,(left,0, right, 15))
left += 15
right += 15
name+=os.path.dirname(i)[-1]
print(name)
result.save("E:/svm/new/"+name+".png")
if __name__ == '__main__':
for i in range(10000):
all = []
getpic()
print(i)
數據集有了,跑完之後識別一下發現效果還可以。但是整體上來說問題還是有的。
問題總結
- python 3.7不能直接使用
pip install tensorflow
python3.5,3.6版本可以 - 合圖方法還需要完善,因爲在訓練的時候,它會自己建一個[0-Z]的文件夾,並將圖片切好放進去,但是有一些圖片會切出去空的文件,所以在訓練數據的時候會報錯,類似這種
cv2.error: /home/arthurckl/Desktop/opencv-3.0.0-rc1/modules/imgproc/src/color.cpp:7564: error: (-215) scn == 3 || scn == 4 in function cvtColor
,所以需要將空文件都刪除。 - 作爲菜鳥還需要繼續提高。開始慢慢啃ML相關知識了,python也得往回撿撿不然就會像這篇文章裏的剪牛鬃一樣了。
願世界沒有bug