1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 机器学习实战案例—验证码(CAPTCHA)识别基于Logistic

机器学习实战案例—验证码(CAPTCHA)识别基于Logistic

时间:2023-02-23 06:03:35

相关推荐

机器学习实战案例—验证码(CAPTCHA)识别基于Logistic

基于Logistic验证码识别

基于逻辑回归(Logistic)图像处理实现数字验证码的识别一、准备数据(制作验证码)二、对图形进行处理三、将数据带入逻辑回归进行建模四、得到模形,进行图像验证 相关技术

基于逻辑回归(Logistic)图像处理实现数字验证码的识别

一、准备数据(制作验证码)

通过在画布获取的随机数字(随机颜色),在添加干扰元素(噪点,噪线)

from PIL import Imagefrom PIL import ImageDraw,ImageFontimport randomdef getRandomColor():"""获取一个随机颜色RGB格式的(r,g,b)如果获取到白色将其传为黑色"""r = random.randint(0, 255)g = random.randint(0, 255)b = random.randint(0, 255)if (r, g, b) == (0, 0, 0):(r, g, b) = (255, 255, 255)return (r, g, b)def getRandmStr():"""获取一个随机数字且每个数字颜色也是随机的"""random_num =str(random.randint(0,9))return random_numdef generate_captcha():#获取一个Image对象,参数分别是RGB模式,宽150,高50,背景为白色image =Image.new('RGB',(150,50),(255,255,255))#获取一个画笔对象,将图片对象传过去draw = ImageDraw.Draw(image)#获取一个font字体对象参数是ttf的字体文件的目录,以及字体的大小font = ImageFont.truetype("LiberationSans-Bold.ttf",size=32)label =""for i in range(5):random_char =getRandmStr()label += random_char#在图片上写东西,参数是:定位,字符串,颜色,字体draw.text((10+i*30,0),random_char,getRandomColor(),font=font)##噪点噪线width =150height =30#画线for i in range(4):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)#arc 弧线draw.arc((x, y, x + 4, y + 4), 0, 90, fill=(0, 0, 0))#保存到硬盘,名为test.png格式的图片image.save(open(''.join(['captcha_images/',label,'.png']),'wb'),'png')if __name__ == '__main__':for i in range(150):generate_captcha()

二、对图形进行处理

【1】二值化:将图像从RGB3通道转化成Gray1通道,然后将Gray灰度值(0~255)转化为二值图(0,1)

0:黑色 1:白色

【2】降噪:通过孤立点,对二值化的图片进行降噪

【3】图片切割:根据像素格进行切割

from PIL import Imageimport numpy as npimport matplotlib.pyplot as pltimport os##binarization二值化def binarization(path):img =Image.open(path)#img.convert('L')将img转化为灰度图img_gray =img.convert('L')img_gray =np.array(img_gray)w,h =img_gray.shapefor x in range(w):for y in range(h):gray = img_gray[x,y]if gray <= 254:img_gray[x,y] = 0else:img_gray[x,y] = 1plt.figure('')plt.imshow(img_gray,cmap='gray')plt.axis('off')plt.show()return img_graydef noiseReduction(img_gray,label):"""降噪"""height,width =img_gray.shapefor x in range(height):for y in range(width):cont =0#白色的点不用管if img_gray[x,y]==1:continueelse:#判断该点周围黑点的个数try:if img_gray[x-1,y-1]==0:cont +=1except:passtry:if img_gray[x-1,y]==0:cont +=1except:passtry:if img_gray[x-1,y+1]==0:cont +=1except:passtry:if img_gray[x,y-1]==0:cont +=1except:passtry:if img_gray[x,y+1]==0:cont +=1except:passtry:if img_gray[x+1,y-1]==0:cont +=1except:passtry:if img_gray[x+1,y]==0:cont +=1except:passtry:if img_gray[x+1,y+1]==0:cont +=1except:pass#如果该点周围黑点个数小于4个,将其去掉## 周围少于4点就算是噪点if cont < 4:img_gray[x,y] =1plt.figure('')plt.imshow(img_gray,cmap='gray')plt.axis('off')plt.savefig(''.join(['clean_captcha_img/',label,'.png']))def create_dir():"创建存放0-9数字的文件夹"for i in range(10):os.mkdir(''.join(['cut_number/',str(i)]))def img_2_clean():"""将原数据进行二值化和降噪处理"""captchas= os.listdir(''.join(['captcha_images/']))for captcha in captchas:label =captcha.split('.')[0]img_path =''.join(['captcha_images/',captcha])im = binarization(img_path)noiseReduction(im,label)def clean_to_cut():"将二值化,降噪后的文件名分开,将前部分传给cutImg"captchas = os.listdir(''.join(['clean_captcha_img/']))for captcha in captchas:label =captcha.split('.')[0]cutImg(label)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(label[i])pic.save(''.join(['cut_number/',str(label[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) + 1if __name__ == '__main__':create_dir()img_2_clean()clean_to_cut()

三、将数据带入逻辑回归进行建模

【1】把切割好的数据,按照X(二维数组),Y(一维数组)的方式传入LogisticRegression.fit()函数进行拟合;(可以通过网格搜索GridSearch来进行调参)

【2】通过jonlib包将创建好的模形保存到本地,之后验证数据速度很快

四、得到模形,进行图像验证

【0】根据步骤一,生成测试图片

【1】根据步骤二,重复操作新的图像

【2】对切割好的每一个图像都进行独立的预测(有点像手写识别系统识别数字)

【3】把最后预测的结果进行拼接

import osfrom PIL import Imageimport numpy as npfrom sklearn.model_selection import train_test_splitfrom sklearn.linear_model import LogisticRegressionfrom sklearn.externals import joblibfrom captcha_logistic 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 <=254: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=10000)log_clf.fit(X_train,Y_train)joblib.dump(log_clf,'captcha_model/captcha_model.model')def get_model():model =joblib.load('captcha_model/captcha_model.model')return modeldef capthca_predict():path ='captcha_images/unknown.png'pre_img_gray =binarization(path)noiseReduction(pre_img_gray,'unknown')#切割测试图片labels =['0','1','2','3','4']img =Image.open(''.join(['clean_captcha_img/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 <= 240:img_array[x, y] = 0else:img_array[x, y] = 1img_re = img_array.reshape(1, -1)# -1 指n列X = img_re[0]y_pre = model.predict([X])result = ''.join([result, str(y_pre[0])])return resultif __name__ == '__main__':X,Y =load_data()#generate_model(X,Y)model = get_model()result = capthca_predict()print(result)

相关技术

分类:Logistic模形选择:网格搜索、查准率、查全率、混淆矩阵、准确率(score)图像处理技术:RGB转灰度在转二值、8位降噪、图像切割

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。