深度學習案例之 驗證碼識別

本項目介紹利用深度學習技術(tensorflow),來識別驗證碼(4位驗證碼,具體的驗證碼的長度可以自己生成,可以在自己進行訓練)

程序分為四個部分

1、生成驗證碼的程序,可生成數字+字母大小寫的任意長度驗證碼

# coding:utf-8
# name:captcha_gen.pyimport random
import numpy as np
from PIL import Image
from captcha.image import ImageCaptchaNUMBER = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
LOW_CASE = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u','v', 'w', 'x', 'y', 'z']
UP_CASE = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U','V', 'W', 'X', 'Y', 'Z']CAPTCHA_LIST = NUMBER
CAPTCHA_LEN = 4         # 驗證碼長度
CAPTCHA_HEIGHT = 60     # 驗證碼高度
CAPTCHA_WIDTH = 160     # 驗證碼寬度def random_captcha_text(char_set=CAPTCHA_LIST, captcha_size=CAPTCHA_LEN):"""隨機生成定長字符串:param char_set: 備選字符串列表:param captcha_size: 字符串長度:return: 字符串"""captcha_text = [random.choice(char_set) for _ in range(captcha_size)]return ''.join(captcha_text)def gen_captcha_text_and_image(width=CAPTCHA_WIDTH, height=CAPTCHA_HEIGHT, save=None):"""生成隨機驗證碼:param width: 驗證碼圖片寬度:param height: 驗證碼圖片高度:param save: 是否保存(None):return: 驗證碼字符串,驗證碼圖像np數組"""image = ImageCaptcha(width=width, height=height)# 驗證碼文本captcha_text = random_captcha_text()captcha = image.generate(captcha_text)# 保存if save:image.write(captcha_text, './img/' + captcha_text + '.jpg')captcha_image = Image.open(captcha)# 轉化為np數組captcha_image = np.array(captcha_image)return captcha_text, captcha_imageif __name__ == '__main__':t, im = gen_captcha_text_and_image(save=True)print(t, im.shape)      # (60, 160, 3)

?2、工具庫,用于調用驗證碼生成程序來生成訓練集

# -*- coding:utf-8 -*-
# name: util.pyimport numpy as np
from captcha_gen import gen_captcha_text_and_image
from captcha_gen import CAPTCHA_LIST, CAPTCHA_LEN, CAPTCHA_HEIGHT, CAPTCHA_WIDTHdef convert2gray(img):"""圖片轉為黑白,3維轉1維:param img: np:return:  灰度圖的np"""if len(img.shape) > 2:img = np.mean(img, -1)return imgdef text2vec(text, captcha_len=CAPTCHA_LEN, captcha_list=CAPTCHA_LIST):"""驗證碼文本轉為向量 啞編碼 方式:param text::param captcha_len::param captcha_list::return: vector 文本對應的向量形式"""text_len = len(text)    # 欲生成驗證碼的字符長度if text_len > captcha_len:raise ValueError('驗證碼最長4個字符')vector = np.zeros(captcha_len * len(captcha_list))      # 生成一個一維向量 驗證碼長度*字符列表長度for i in range(text_len):vector[captcha_list.index(text[i])+i*len(captcha_list)] = 1     # 找到字符對應在字符列表中的下標值+字符列表長度*i 的 一維向量 賦值為 1return vectordef vec2text(vec, captcha_list=CAPTCHA_LIST, captcha_len=CAPTCHA_LEN):"""驗證碼向量轉為文本:param vec::param captcha_list::param captcha_len::return: 向量的字符串形式"""vec_idx = vectext_list = [captcha_list[int(v)] for v in vec_idx]return ''.join(text_list)def wrap_gen_captcha_text_and_image(shape=(CAPTCHA_HEIGHT, CAPTCHA_WIDTH, 3)):"""返回特定shape圖片:param shape::return:"""while True:t, im = gen_captcha_text_and_image()if im.shape == shape:return t, imdef get_next_batch(batch_count=60, width=CAPTCHA_WIDTH, height=CAPTCHA_HEIGHT):"""獲取訓練圖片組:param batch_count: default 60:param width: 驗證碼寬度:param height: 驗證碼高度:return: batch_x, batch_yc"""batch_x = np.zeros([batch_count, width * height])batch_y = np.zeros([batch_count, CAPTCHA_LEN * len(CAPTCHA_LIST)])for i in range(batch_count):    # 生成對應的訓練集text, image = wrap_gen_captcha_text_and_image()image = convert2gray(image)     # 轉灰度numpy# 將圖片數組一維化 同時將文本也對應在兩個二維組的同一行batch_x[i, :] = image.flatten() / 255batch_y[i, :] = text2vec(text)  # 驗證碼文本的向量形式# 返回該訓練批次return batch_x, batch_yif __name__ == '__main__':x, y = get_next_batch(batch_count=1)    # 默認為1用于測試集print(x, y)

3、訓練程序,并將準確率超過0.95的模型保存到 ./model/ 文件夾下

# -*- coding:utf-8 -*-
# name: model_train.pyimport tensorflow as tf
from datetime import datetime
from util import get_next_batch
from captcha_gen import CAPTCHA_HEIGHT, CAPTCHA_WIDTH, CAPTCHA_LEN, CAPTCHA_LISTdef weight_variable(shape, w_alpha=0.01):"""初始化權值:param shape::param w_alpha::return:"""initial = w_alpha * tf.random_normal(shape)return tf.Variable(initial)def bias_variable(shape, b_alpha=0.1):"""初始化偏置項:param shape::param b_alpha::return:"""initial = b_alpha * tf.random_normal(shape)return tf.Variable(initial)def conv2d(x, w):"""卷基層 :局部變量線性組合,步長為1,模式‘SAME’代表卷積后圖片尺寸不變,即零邊距:param x::param w::return:"""return tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME')def max_pool_2x2(x):"""池化層:max pooling,取出區域內最大值為代表特征, 2x2 的pool,圖片尺寸變為1/2:param x::return:"""return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')def cnn_graph(x, keep_prob, size, captcha_list=CAPTCHA_LIST, captcha_len=CAPTCHA_LEN):"""三層卷積神經網絡:param x:   訓練集 image x:param keep_prob:   神經元利用率:param size:        大小 (高,寬):param captcha_list::param captcha_len::return: y_conv"""# 需要將圖片reshape為4維向量image_height, image_width = sizex_image = tf.reshape(x, shape=[-1, image_height, image_width, 1])# 第一層# filter 定義為3x3x1, 輸出32個特征, 即32個filterw_conv1 = weight_variable([3, 3, 1, 32])    # 3*3的采樣窗口,32個(通道)卷積核從1個平面抽取特征得到32個特征平面b_conv1 = bias_variable([32])h_conv1 = tf.nn.relu(conv2d(x_image, w_conv1) + b_conv1)    # rulu激活函數h_pool1 = max_pool_2x2(h_conv1)     # 池化h_drop1 = tf.nn.dropout(h_pool1, keep_prob)      # dropout 防止過擬合# 第二層w_conv2 = weight_variable([3, 3, 32, 64])b_conv2 = bias_variable([64])h_conv2 = tf.nn.relu(conv2d(h_drop1, w_conv2) + b_conv2)h_pool2 = max_pool_2x2(h_conv2)h_drop2 = tf.nn.dropout(h_pool2, keep_prob)# 第三層w_conv3 = weight_variable([3, 3, 64, 64])b_conv3 = bias_variable([64])h_conv3 = tf.nn.relu(conv2d(h_drop2, w_conv3) + b_conv3)h_pool3 = max_pool_2x2(h_conv3)h_drop3 = tf.nn.dropout(h_pool3, keep_prob)"""原始:60*160圖片 第一次卷積后 60*160 第一池化后 30*80*32第二次卷積后 30*80*32 ,第二次池化后 15*40*64第三次卷積后 15*40*64 ,第三次池化后 7.5*20*64 = > 向下取整 7*20*64經過上面操作后得到 64 個 7*20的平面"""# 全連接層image_height = int(h_drop3.shape[1])image_width = int(h_drop3.shape[2])w_fc = weight_variable([image_height*image_width*64, 1024])     # 上一層有64個神經元 全連接層有1024個神經元b_fc = bias_variable([1024])h_drop3_re = tf.reshape(h_drop3, [-1, image_height*image_width*64])h_fc = tf.nn.relu(tf.matmul(h_drop3_re, w_fc) + b_fc)h_drop_fc = tf.nn.dropout(h_fc, keep_prob)# 輸出層w_out = weight_variable([1024, len(captcha_list)*captcha_len])b_out = bias_variable([len(captcha_list)*captcha_len])y_conv = tf.matmul(h_drop_fc, w_out) + b_outreturn y_convdef optimize_graph(y, y_conv):"""優化計算圖:param y: 正確值:param y_conv:  預測值:return: optimizer"""# 交叉熵代價函數計算loss 注意 logits 輸入是在函數內部進行sigmod操作# sigmod_cross適用于每個類別相互獨立但不互斥,如圖中可以有字母和數字# softmax_cross適用于每個類別獨立且排斥的情況,如數字和字母不可以同時出現loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=y, logits=y_conv))# 最小化loss優化 AdaminOptimizer優化optimizer = tf.train.AdamOptimizer(1e-3).minimize(loss)return optimizerdef accuracy_graph(y, y_conv, width=len(CAPTCHA_LIST), height=CAPTCHA_LEN):"""偏差計算圖,正確值和預測值,計算準確度:param y: 正確值 標簽:param y_conv:  預測值:param width:   驗證碼預備字符列表長度:param height:  驗證碼的大小,默認為4:return:    正確率"""# 這里區分了大小寫 實際上驗證碼一般不區分大小寫,有四個值,不同于手寫體識別# 預測值predict = tf.reshape(y_conv, [-1, height, width])   #max_predict_idx = tf.argmax(predict, 2)# 標簽label = tf.reshape(y, [-1, height, width])max_label_idx = tf.argmax(label, 2)correct_p = tf.equal(max_predict_idx, max_label_idx)    # 判斷是否相等accuracy = tf.reduce_mean(tf.cast(correct_p, tf.float32))return accuracydef train(height=CAPTCHA_HEIGHT, width=CAPTCHA_WIDTH, y_size=len(CAPTCHA_LIST)*CAPTCHA_LEN):"""cnn訓練:param height:  驗證碼高度:param width:   驗證碼寬度:param y_size:  驗證碼預備字符列表長度*驗證碼長度(默認為4):return:"""# cnn在圖像大小是2的倍數時性能最高, 如果圖像大小不是2的倍數,可以在圖像邊緣補無用像素# 在圖像上補2行,下補3行,左補2行,右補2行# np.pad(image,((2,3),(2,2)), 'constant', constant_values=(255,))acc_rate = 0.95     # 預設模型準確率標準# 按照圖片大小申請占位符x = tf.placeholder(tf.float32, [None, height * width])y = tf.placeholder(tf.float32, [None, y_size])# 防止過擬合 訓練時啟用 測試時不啟用 神經元使用率keep_prob = tf.placeholder(tf.float32)# cnn 模型y_conv = cnn_graph(x, keep_prob, (height, width))# 優化optimizer = optimize_graph(y, y_conv)# 計算準確率accuracy = accuracy_graph(y, y_conv)# 啟動會話.開始訓練saver = tf.train.Saver()sess = tf.Session()sess.run(tf.global_variables_initializer())     # 初始化step = 0    # 步數while 1:print(step)batch_x, batch_y = get_next_batch(64)sess.run(optimizer, feed_dict={x: batch_x, y: batch_y, keep_prob: 0.75})# 每訓練一百次測試一次if step % 10 == 0:batch_x_test, batch_y_test = get_next_batch(100)acc = sess.run(accuracy, feed_dict={x: batch_x_test, y: batch_y_test, keep_prob: 1.0})print(datetime.now().strftime('%c'), ' step:', step, ' accuracy:', acc)# 準確率滿足要求,保存模型if acc > acc_rate:model_path = "./model/captcha.model"saver.save(sess, model_path, global_step=step)acc_rate += 0.01if acc_rate > 0.99:     # 準確率達到99%則退出breakstep += 1sess.close()if __name__ == '__main__':train()

4、測試模型效果:

# -*- coding:utf-8 -*-
# name: model_test.pyimport tensorflow as tf
from model_train import cnn_graph
from captcha_gen import gen_captcha_text_and_image
from util import vec2text, convert2gray
from util import CAPTCHA_LIST, CAPTCHA_WIDTH, CAPTCHA_HEIGHT, CAPTCHA_LEN
from PIL import Imagedef captcha2text(image_list, height=CAPTCHA_HEIGHT, width=CAPTCHA_WIDTH):"""驗證碼圖片轉化為文本:param image_list::param height::param width::return:"""x = tf.placeholder(tf.float32, [None, height * width])keep_prob = tf.placeholder(tf.float32)y_conv = cnn_graph(x, keep_prob, (height, width))saver = tf.train.Saver()with tf.Session() as sess:saver.restore(sess, tf.train.latest_checkpoint('model/'))predict = tf.argmax(tf.reshape(y_conv, [-1, CAPTCHA_LEN, len(CAPTCHA_LIST)]), 2)vector_list = sess.run(predict, feed_dict={x: image_list, keep_prob: 1})vector_list = vector_list.tolist()text_list = [vec2text(vector) for vector in vector_list]return text_listif __name__ == '__main__':text, image = gen_captcha_text_and_image()img = Image.fromarray(image)image = convert2gray(image)image = image.flatten() / 255pre_text = captcha2text([image])print("驗證碼正確值:", text, ' 模型預測值:', pre_text)img.show()

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/453957.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/453957.shtml
英文地址,請注明出處:http://en.pswp.cn/news/453957.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

windows下使用pthread庫

最近在看《C多核高級編程》這本書,收集了些有用的東西,方便在windows下使用POSIX標準進行Pthread開發,有利于跨平臺。 -------------------------------------------------- windows下使用pthread庫時間:2010-01-27 07:41來源:羅索工作室 作…

day 05 多行輸出與多行注釋、字符串的格式化輸出、預設創建者和日期

msg"hello1 hello2 hello3 " print(msg) 顯示結果為: # " "只能進行單行的字符串 多行字符串用 ,前面設置變量,可以用 表示多行 msghello1 hello2 hello3print(msg) 顯示結果為: 當然如果沒有設置變量,…

python數值計算guess_【python】猜數字game,旨在提高初學者對Python循環結構的使用...

import random #引入生成隨機數的模塊需求:程序設定生成 1-20 之間的一個隨機數,讓用戶猜日期:2019-10-21作者:xiaoxiaohui目的:猜數字game,旨在提高初學者對Python 變量類型以及循環結構的使用。secretNu…

調試九法-總體規則

調試規則規則1 理解系統規則2 制造失敗規則3 不要想,而要看規則4 分而治之規則5 一次只改一個地方規則6 保持審計跟蹤規則7 檢查插頭規則8 獲得全新觀點規則9 如果你不修復bug,它將依然存在轉載于:https://www.cnblogs.com/uetucci/p/7987805.html

深度學習之循環神經網絡(Recurrent Neural Network,RNN)

遞歸神經網絡和循環神經網絡 循環神經網絡(recurrent neural network):時間上的展開,處理的是序列結構的信息,是有環圖遞歸神經網絡(recursive neural network):空間上的展開&#…

從北京回來的年輕人,我該告訴你點什么?

前言 就在上周末,我與公眾號里的一個當地粉絲見面了,一起吃了頓飯,順便聊了聊。先來簡單交代下我們這位粉絲(以下簡稱小L)的經歷以及訴求。 小L之前在北京八維研修學院培訓的PHP,因為家庭原因,沒…

Linphone編譯【轉載】

Linphone依賴太多的庫,以致于稍有疏失,就會在編譯,運行出錯,都是由于依賴庫安裝的問題。 1 基礎知識 1.1 動態庫的連接 很多人安裝完庫后,configure依然報告這個庫沒有。這是對linux動態庫知識匱乏造成,也就…

python助教的面試題_python面試題----持續更新中

為什么學習Python?通過什么途徑學習的Python?Python和Java、PHP、C、C#、C等其他語言的對比?python 解釋型語言,語法簡潔優雅。C C 編譯型語言,先編譯后運行,偏底層。簡述解釋型和編譯型編程語言&#xff1…

python3模塊: requests

Python標準庫中提供了:urllib等模塊以供Http請求,但是,它的 API 太渣了。它是為另一個時代、另一個互聯網所創建的。它需要巨量的工作,甚至包括各種方法覆蓋,來完成最簡單的任務。 發送GET請求 import urllib.requestf…

SUSE12系統安裝及LVM設置詳解

SUSE12自定義安裝跟以往版本差不多,只是調整了一些功能安裝順序,例如網絡設置放到很靠前,SUSE11的時候幾乎是在后半部分,自定義分區也調整到網絡設置之后,入口設置也隱秘,如果是熟悉suse11安裝,…

在windows下編譯FFMPEG-最新2009版本

轉】在windows下編譯FFMPEG-最新2009版本2010-11-17 18:50大家可以看到,此篇之前有很多個版本的“在windows下編譯FFMPEG”,那些都是我在網上搜羅來的,在看了無數篇那些過期的、有借鑒價值的文章后,我終于成功在windows下編譯出了…

CentOS7 安裝nginx

1、官網下載安裝包 官網:http://nginx.org/en/download.html 選擇適合Linux的版本,這里選擇最新的版本,下載到本地后上傳到服務器或者centos下直接wget命令下載。 切換到/usr/local目錄,下載軟件包 # cd /usr/local # wget htt…

dvwa如何打開_DVWA詳細 安裝

Wamp就是Windows Apache Mysql PHP集成安裝環境,即在window下的apache、php和mysql的服務器軟件。PHP擴展、Apache模塊,開啟/關閉鼠標點點就搞定,再也不用親自去修改配置文件了,WAMP它會去做。再也不用到處詢問php的安裝問題了&am…

CentOS7安裝OpenFire

下載openfire wget http://download.igniterealtime.org/openfire/openfire-3.9.3-1.i386.rpm安裝openfire yum install -y /home/openfire-3.9.3-1.i386.rpm安裝運行庫 yum install -y glibc.i686添加開啟啟動 chkconfig openfire on啟動openfire服務 systemctlstart openfire…

CentOS 安裝 php

大致步驟:下載–解壓–編譯–安裝–配置 php官網: https://www.php.net/releases/ php5.6連接地址 http://hk1.php.net/get/php-5.6.36.tar.gz/from/this/mirror http://hk2.php.net/get/php-5.6.36.tar.gz/from/this/mirror 1.安裝php 所依賴的軟件 yu…

怎么利用ffmpeg和AviSynth給在windows下面為flv文件加水印

之前一直在找怎么為flv文件加上自己的水印,ffmpeg和vhook是在linux下面支持.在windows下面不支持.所以我就選擇用ffmpeg和AviSynth為flv文件加水印.詳細步驟如下: 1 首先當然下載ffmpeg和AviSynth了.具體的地址自己google一下就能找到很多.這里就不再詳細介紹了. 一般情況ffm…

【Hibernate框架開發之九】Hibernate 性能優化筆記!(遍歷、一級/二級/查詢/緩存/樂觀悲觀鎖等優化算法)...

1. 循環分頁或者循環進行部分讀取處理數據的時候,使用 session.clear() ; 2. 對應1N(N1)問題使用如下解決方式: 1): 使用createCriteria進行查詢(join fetch) 2):HQL -> joi…

vscode中安裝webpack_VSCode下手動構建webpack項目(示例代碼)

1.執行npm install nrm -g,安裝nrm,此模塊主要用于切換npm鏡像源,簡化手動配置步驟2.執行 nrm ls,可以看到npm源地址列表,當前使用的是默認源,npm https://registry.npmjs.org/3.執行 nrm use taobao&#…

Python html 代碼轉成 word(docx)

安裝 sudo apt install pandoc pip3 install pypandoc示例代碼 import pypandochtml """ <h3>This is a title</h3> <p><img src"http://placehold.it/150x150" alt"I go below the image as a caption"></p…

最新ffmpeg編譯和用eclipse進行源碼調試

最近由于項目需要&#xff0c;必須修改ffmpeg的源碼進行修改才能滿足項目的需求&#xff0c;但以前我從來沒有自己去編譯和使用ffmpeg的源代碼&#xff0c;一直都是用別人編譯好了的sdk&#xff0c;再加上習慣了vs方便的編譯環境&#xff0c;要在linux下對如此多的源代碼進行編…