聲明:文章僅源自個人興趣愛好,不涉及他用,侵權聯繫刪。
轉載請註明:轉自此博文https://leejason.blog.csdn.net/article/details/106150572
TensorFlow+CNN+OpenCV快速識別中文驗證碼
1 項目簡介
本項目使用了卷積神經網絡(CNN),基於TensorFlow深度學習框架,該框架封裝了非常通用的校驗、訓練、驗證、識別和調用 API,兩者結合極大地降低了驗證碼識別的成本和時間精力。
當初剛接觸神經網絡這塊寫的一個項目,網格什麼的都是採用最簡單的,也沒有優化什麼的。但是識別率的話達到99.99%,基本百分百了,處理此次驗證碼基本是足夠了。
1.1 關於驗證碼識別
驗證碼識別大多是爬蟲會遇到的問題,也可以作爲圖像識別的入門案例。這裏介紹一下使用傳統的圖像處理和機器學習算法,它們都涉及多種技術:
圖像處理
-
前處理(灰度化、二值化)
-
圖像分割
-
裁剪(去邊框)
-
圖像濾波、降噪
-
去背景
-
顏色分離
-
旋轉
機器學習
- KNN
- SVM
使用這類方法對使用者的要求較高,且由於圖片的變化類型較多,處理的方法不夠通用,經常花費很多時間去調整處理步驟和相關算法。
而使用卷積神經網絡,只需要通過簡單的前處理,就可以實現大部分靜態字符型驗證碼的端到端識別,效果很好、通用性很高。
1.2 此次識別的驗證碼類型
驗證碼圖片如下
概括一下,就是中文漢字驗證碼,漢字帶有字體,外加背景干擾。
1.3 最初解決方法
最初,是藉助打碼平臺解決的,一張驗證碼圖片40積分(摺合人民幣4分錢一次),對於每天請求幾萬、幾十萬次來說,長時間下來是筆不小的開支了,所以自行識別驗證碼就顯得很有必要。
1.4 項目文件
文件名 | 說明 |
---|---|
process_picture.py | right-aligned 文本居右 |
different_test.py | 測試文件 |
train_saveModel.py | 讀取文件及訓練模型扥 |
restore_predict.py | 加載模型預測 |
files | 存放初始驗證碼、訓練好的模型 |
captcha | 處理過的驗證碼圖片 |
1.5 涉及到的python庫
- tensorflow
- requests
- matplotlib
- pandas
- numpy
- cv2
- re
- os
- glob
1.6 模型結構
採用先對簡單的兩層卷積+全連接:
序號 | 層級 |
---|---|
輸入 | input |
1 | 卷積層+激活層+池化層 |
2 | 卷積層+激活層+池化層 |
3 | 全連接層 |
輸出 | output |
2 項目流程
2.1 採集驗證碼圖片
要識別驗證碼,就需要大量的驗證碼圖片用來構建訓練集與測試集,所以用爬蟲腳本抓取了20000張驗證碼圖片:
採集效果:
2.2 處理圖片
2.2.1 灰度化效果
2.2.2 二值化效果
2.2.3 圖像濾波、降噪:
二值化和灰度化後就使噪點顯得很明顯了,因爲不是很懂圖像處理這塊,還專門花了點時間去學了下OpenCV, 雖然最終還是請教了下做圖像處理的同學,很感謝他給予的幫助。
處理出後的大致效果如圖
去除了背景干擾,每個字的大小和輪廓都是差不多的,所以覺得用深度學習算法識別正確率應該會大大提高。
圖像處理整體代碼:
2.3 構建目標值
有了圖片,那麼就需要建立圖片與圖片漢字(目標值)對應關係,本來打算藉助百度智能雲識別的,但是不管是原圖,還是處理後的圖片都是幾乎識別不出來的,最後無奈,還是選擇了打碼平臺,構建了labels.csv,如圖:
2.4 讀取圖片
def readPic():
path = r"./captcha"
files_list = glob.glob(path+"/*.png")
#構造隊列
file_queue = tf.train.string_input_producer(files_list)
reader = tf.WholeFileReader()
key,value = reader.read(file_queue)
image_decoded = tf.image.decode_jpeg(value)
image_resized = tf.image.resize(image_decoded,[20,100])
#更新靜態形狀
image_resized.set_shape([20,100,1])
image_cast = tf.cast(image_resized,tf.float32)
#批處理
filename_batch,image_batch = tf.train.batch([key,image_cast],batch_size=50,num_threads=2,capacity=50)
return filename_batch,image_batch
2.5 建立文件名與特徵值映射
2.6 再次建立此次讀取 文件名 與 特徵值 之間的聯繫
def filename2label(filenames,df):
'''
將filename 和 標籤值 對應
:param filenames: 文件名,格式爲 b' 二進制格式
:param df:DataFrame 字母 和 對應的初步目標值構成
:return: labels ndarray
'''
labels = []
# print(df)
for filename in filenames:
name = re.findall(r'(\d+)\.png',str(filename))
if name:
label = df.loc[int(name[0]),"labels"]
labels.append(label)
return np.array(labels)
2.7 構建卷積神經網絡,獲取y_predict
2.8 構造損失函數
loss_list = tf.nn.sigmoid_cross_entropy_with_logits(labels=y_true, logits=y_predict)
loss = tf.reduce_mean(loss_list)
2.9 優化損失
optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)
2.10 計算準確率
equal_list = tf.reduce_all(
tf.equal(tf.argmax(tf.reshape(y_predict, shape=[-1, 4, 30]), axis=2),
tf.argmax(tf.reshape(y_true, shape=[-1, 4, 30]), axis=2)), axis=1)#按行,1axis=1或者-1
accuracy = tf.reduce_mean(tf.cast(equal_list, tf.float32))
2.11 模型訓練與保存
3 預測
隨機選擇一張驗證碼圖片:
處理後的:
預測結果:
文章很多語言及文章排版格式參考自機器之心的中文項目:快速識別驗證碼,CNN也能爲爬蟲保駕護航