验证码识别逻辑回归案例
應用案例
本案例利用邏輯回歸實現驗證碼中數字識別
第一步:生成驗證碼圖片訓練集
from PIL import Image from PIL import ImageDraw from PIL import ImageFont import randomdef getRandomColor():"""獲取一個隨機顏色(r,g,b)格式的:return:"""c1 = random.randint(0, 255)c2 = random.randint(0, 255)c3 = random.randint(0, 255)if c1 == 255:c1 = 0if c2 == 255:c2 = 0if c3 == 255:c3 = 0return(c1, c2, c3)def getRandomStr():"""獲取一個隨機數字,每個數字的顏色也是隨機的:return:"""random_num = str(random.randint(0, 9))return random_num ()() def generate_captcha():# 獲取一個Image對象,參數分別是RGB模式。寬150,高30, 隨機顏色image = Image.new('RGB', (150, 50), (255,255,255))# 獲取一個畫筆對象,將圖片對象傳過去draw = ImageDraw.Draw(image)# 獲取一個font字體對象參數是ttf的字體文件的目錄,以及字體的大小font = ImageFont.truetype("ARLRDBD.TTF", size=32)label = ""for i in range(5):random_char = getRandomStr()label += random_char# 在圖片上寫東西,參數是:定位,字符串,顏色,字體draw.text((10+i*30, 0), random_char, getRandomColor(), font=font)# 噪點噪線width = 150height = 30# 畫線for i in range(3):x1 = random.randint(0, width)x2 = random.randint(0, width)y1 = random.randint(0, height)y2 = random.randint(0, height)draw.line((x1, y1, x2, y2), fill=(0, 0, 0))# 畫點for i in range(5):draw.point([random.randint(0, width), random.randint(0, height)], fill=getRandomColor())x = random.randint(0, width)y = random.randint(0, height)draw.arc((x, y, x + 4, y + 4), 0, 90, fill=(0, 0, 0))# 保存到硬盤,名為test.png格式為png的圖片image.save(open(''.join(['captcha_images/', label, '.png']), 'wb'), 'png')# image.save(open(''.join(['captcha_predict/', label, '.png']), 'wb'), 'png') if __name__ == '__main__':for i in range(150):generate_captcha()可以看到captcha_images/文件夾下有150張隨機驗證碼生成
第二步:去掉噪聲
由于我們生成驗證碼時為了盡可能模仿平時見到的驗證碼,我們給驗證碼加入了噪點和噪線,為了提高識別的準確率,我們首先要去掉這些噪聲。這里去掉噪點我們使用的算法如下:
首先把生成的圖片二值化,黑色像素點為0,白色像素點為1,白色像素點我們不需要進行任何處理,我們比較每一個黑色像素點周圍的八個像素點是否是黑色,若周圍八個像素點有少于四個是黑色的,那我們就把該像素點判斷為噪點,使該像素點的值變為1,即變成白色。
代碼如下:
去噪后的驗證碼如下所示:
第三步:切分驗證碼中的數字
在進行模型訓練時,我們需要去訓練驗證碼中的每一個單獨的數字而不是一張驗證碼圖片,所以我們要把每一張驗證碼中的數字切分出來,相同數值的數字放在同一個文件夾,代碼如下:
def cutImg(label):labels = list(label)img = Image.open(''.join(['clean_captcha_img/', label, '.png']))for i in range(5):pic = img.crop((100*(1+i), 170, 100*(1+i)+100, 280))plt.imshow(pic)seq = get_save_seq(labels[i])pic.save(''.join(['cut_number/', str(labels[i]), '/', str(seq), '.png']))def get_save_seq(num):numlist = os.listdir(''.join(['cut_number/', num, '/']))if len(numlist) == 0 or numlist is None:return 0else:max_file = 0for file in numlist:if int(file.split('.')[0]) > max_file:max_file = int(file.split('.')[0])return int(max_file)+1def create_dir():for i in range(10):os.mkdir(''.join(['cut_number/', str(i)]))def clean_to_cut():captchas = os.listdir(''.join(['image_denoise/']))for captcha in captchas:label = captcha.split('.')[0]cutImg(label)切分以后,相同的數字都存在了同一個文件夾,并且文件夾以該數值命名,目的是為了方便生成訓練時的標簽值
第四步:生成模型
第三步我們已經處理好了數據集,接下來我門把數據格式變為訓練所需要的數據格式,然后利用邏輯回歸生成模型,模型保存在captcha_model/文件夾中
import os from PIL import Image import numpy as np from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression from sklearn.externals import joblib import matplotlib.pyplot as pltfrom day05.captcha_generator import *def load_data():X,Y=[],[]cut_list = os.listdir('cut_number')for numC in cut_list:num_list_dir =''.join(['cut_number/',str(numC),'/'])nums_dir = os.listdir(num_list_dir)for num_file in nums_dir:img=Image.open(''.join(['cut_number/',str(numC),'/',num_file]))img_gray = img.convert('L')img_array = np.array(img_gray)w,h = img_array.shapefor x in range(w):for y in range(h):gray = img_array[x,y]if gray<=240:img_array[x,y]=0else:img_array[x,y]=1img_re = img_array.reshape(1,-1)X.append(img_re[0])Y.append(int(numC))return np.array(X),np.array(Y)def generate_model(X,Y):x_train,x_test,y_train,y_test =train_test_split(X,Y,test_size=0.3)log_clf = LogisticRegression(multi_class='ovr',solver='sag',max_iter=1000)log_clf.fit(x_train,y_train)joblib.dump(log_clf,'captcha_model/captcha_model.model')第五部:加載模型進行預測
首先我們加載模型,隨后生成預測數據,預測數據的生成方法與隨機生存驗證碼代碼相同,我們把生成的預測屬于命名為unknown.png 再把生成的圖片進行去噪切分,再用加載的模型進行預測。
def get_model():model = joblib.load('captcha_model/captcha_model.model')return modeldef capthca_predict():path = 'captcha_predict/unknown.png'pre_img_gray = binarization(path)denoise(pre_img_gray,'unknown')labels = ['0','1','2','3','4']img = Image.open(''.join(['image_denoise/unknown.png']))for i in range(5):pic = img.crop((100*(1+i),170,100*(1+i)+100,280))plt.imshow(pic)pic.save(''.join(['captcha_predict/',labels[i],'.png']))result = ''model=get_model()for i in range(5):path = ''.join(['captcha_predict/',labels[i],'.png'])img = Image.open(path)img_gray = img.convert('L')img_array = np.array(img_gray)w, h = img_array.shapefor x in range(w):for y in range(h):gray = img_array[x, y]if gray <= 220:img_array[x, y] = 0else:img_array[x, y] = 1img_re = img_array.reshape(1,-1)X=img_re[0]y_pre = model.predict([X])result = ''.join([result,str(y_pre[0])])return result我們可以看到生成的預測圖片如下:
預測結果如下:
總結
以上是生活随笔為你收集整理的验证码识别逻辑回归案例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Unity3D 动态加载资源方式
- 下一篇: mac os 安装 s2geometry