电商网站建设新闻,婚介网站方案,wordpress建站 知乎,门户建设网站方案文章目录 0 前言1 项目运行效果2 原理介绍3 验证码识别步骤3.1 灰度处理二值化3.2 去除边框3.3 图像降噪3.4 字符切割3.5 识别3.6 深度学习的验证码识别数据集训练 4 最后 0 前言
#x1f525;这两年开始毕业设计和毕业答辩的要求和难度不断提升#xff0c;传统的毕设题…文章目录0 前言1 项目运行效果2 原理介绍3 验证码识别步骤3.1 灰度处理二值化3.2 去除边框3.3 图像降噪3.4 字符切割3.5 识别3.6 深度学习的验证码识别数据集训练4 最后0 前言这两年开始毕业设计和毕业答辩的要求和难度不断提升传统的毕设题目缺少创新和亮点往往达不到毕业答辩的要求这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。并且很难找到完整的毕设参考学习资料。为了大家能够顺利以及最少的精力通过毕设学长分享优质毕业设计项目提供大家参考学习今天要分享的是毕业设计 基于深度学习的新闻文本分类算法系统(源码论文)学长这里给一个题目综合评分(每项满分5分)难度系数3分工作量3分创新点4分 项目分享:见文末!1 项目运行效果视频效果毕业设计 深度学习验证码识别2 原理介绍这里做一个简单的识别demo说明项目原理实际项目比demo复杂一些。在python爬虫爬取某些网站的验证码的时候可能会遇到验证码识别的问题现在的验证码大多分为四类1、计算验证码2、滑块验证码3、识图验证码4、语音验证码学长这李主要写的就是识图验证码识别的是简单的验证码要想让识别率更高识别的更加准确就需要花很多的精力去训练自己的字体库。3 验证码识别步骤1、灰度处理2、二值化3、去除边框如果有的话4、降噪5、切割字符或者倾斜度矫正6、训练字体库7、识别这6个步骤中前三个步骤是基本的4或者5可根据实际情况选择是否需要并不一定切割验证码识别率就会上升很多有时候还会下降这篇博客不涉及训练字体库的内容请自行搜索。同样也不讲解基础的语法。用到的几个主要的python库 Pillow(python图像处理库)、OpenCV(高级图像处理库)、pytesseract(识别库)3.1 灰度处理二值化灰度处理就是把彩色的验证码图片转为灰色的图片。二值化是将图片处理为只有黑白两色的图片利于后面的图像处理和识别在OpenCV中有现成的方法可以进行灰度处理和二值化处理后的效果# 自适应阀值二值化def_get_dynamic_binary_image(filedir,img_name):filename./out_img/img_name.split(.)[0]-binary.jpgimg_namefiledir/img_nameprint(.....img_name)imcv2.imread(img_name)imcv2.cvtColor(im,cv2.COLOR_BGR2GRAY)#灰值化# 二值化th1cv2.adaptiveThreshold(im,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,21,1)cv2.imwrite(filename,th1)returnth13.2 去除边框如果验证码有边框那我们就需要去除边框去除边框就是遍历像素点找到四个边框上的所有点把他们都改为白色我这里边框是两个像素宽注意在用OpenCV时图片的矩阵点是反的就是长和宽是颠倒的代码# 去除边框defclear_border(img,img_name):filename./out_img/img_name.split(.)[0]-clearBorder.jpgh,wimg.shape[:2]foryinrange(0,w):forxinrange(0,h):ify2oryw-2:img[x,y]255ifx2orxh-2:img[x,y]255cv2.imwrite(filename,img)returnimg效果3.3 图像降噪降噪是验证码处理中比较重要的一个步骤我这里使用了点降噪和线降噪线降噪的思路就是检测这个点相邻的四个点图中标出的绿色点判断这四个点中是白点的个数如果有两个以上的白色像素点那么就认为这个点是白色的从而去除整个干扰线但是这种方法是有限度的如果干扰线特别粗就没有办法去除只能去除细的干扰线# 干扰线降噪definterference_line(img,img_name):filename./out_img/img_name.split(.)[0]-interferenceline.jpgh,wimg.shape[:2]# opencv矩阵点是反的# img[1,2] 1:图片的高度2图片的宽度foryinrange(1,w-1):forxinrange(1,h-1):count0ifimg[x,y-1]245:countcount1ifimg[x,y1]245:countcount1ifimg[x-1,y]245:countcount1ifimg[x1,y]245:countcount1ifcount2:img[x,y]255cv2.imwrite(filename,img)returnimg点降噪的思路和线降噪的差不多只是会针对不同的位置检测的点不一样,注释写的很清楚了# 点降噪definterference_point(img,img_name,x0,y0): 9邻域框,以当前点为中心的田字框,黑点个数 :param x: :param y: :return: filename./out_img/img_name.split(.)[0]-interferencePoint.jpg# todo 判断图片的长宽度下限cur_pixelimg[x,y]# 当前像素点的值height,widthimg.shape[:2]foryinrange(0,width-1):forxinrange(0,height-1):ify0:# 第一行ifx0:# 左上顶点,4邻域# 中心点旁边3个点sumint(cur_pixel)\int(img[x,y1])\int(img[x1,y])\int(img[x1,y1])ifsum2*245:img[x,y]0elifxheight-1:# 右上顶点sumint(cur_pixel)\int(img[x,y1])\int(img[x-1,y])\int(img[x-1,y1])ifsum2*245:img[x,y]0else:# 最上非顶点,6邻域sumint(img[x-1,y])\int(img[x-1,y1])\int(cur_pixel)\int(img[x,y1])\int(img[x1,y])\int(img[x1,y1])ifsum3*245:img[x,y]0elifywidth-1:# 最下面一行ifx0:# 左下顶点# 中心点旁边3个点sumint(cur_pixel)\int(img[x1,y])\int(img[x1,y-1])\int(img[x,y-1])ifsum2*245:img[x,y]0elifxheight-1:# 右下顶点sumint(cur_pixel)\int(img[x,y-1])\int(img[x-1,y])\int(img[x-1,y-1])ifsum2*245:img[x,y]0else:# 最下非顶点,6邻域sumint(cur_pixel)\int(img[x-1,y])\int(img[x1,y])\int(img[x,y-1])\int(img[x-1,y-1])\int(img[x1,y-1])ifsum3*245:img[x,y]0else:# y不在边界ifx0:# 左边非顶点sumint(img[x,y-1])\int(cur_pixel)\int(img[x,y1])\int(img[x1,y-1])\int(img[x1,y])\int(img[x1,y1])ifsum3*245:img[x,y]0elifxheight-1:# 右边非顶点sumint(img[x,y-1])\int(cur_pixel)\int(img[x,y1])\int(img[x-1,y-1])\int(img[x-1,y])\int(img[x-1,y1])ifsum3*245:img[x,y]0else:# 具备9领域条件的sumint(img[x-1,y-1])\int(img[x-1,y])\int(img[x-1,y1])\int(img[x,y-1])\int(cur_pixel)\int(img[x,y1])\int(img[x1,y-1])\int(img[x1,y])\int(img[x1,y1])ifsum4*245:img[x,y]0cv2.imwrite(filename,img)returnimg效果其实到了这一步这些字符就可以识别了没必要进行字符切割了现在这三种类型的验证码识别率已经达到50%以上了3.4 字符切割字符切割通常用于验证码中有粘连的字符粘连的字符不好识别所以我们需要将粘连的字符切割为单个的字符在进行识别字符切割的思路就是找到一个黑色的点然后在遍历与他相邻的黑色的点直到遍历完所有的连接起来的黑色的点找出这些点中的最高的点、最低的点、最右边的点、最左边的点记录下这四个点认为这是一个字符然后在向后遍历点直至找到黑色的点继续以上的步骤。最后通过每个字符的四个点进行切割图中红色的点就是代码执行完后标识出的每个字符的四个点然后就会根据这四个点进行切割图中画的有些误差懂就好但是也可以看到m2是粘连的代码认为他是一个字符所以我们需要对每个字符的宽度进行检测如果他的宽度过宽我们就认为他是两个粘连在一起的字符并将它在从中间切割确定每个字符的四个点代码defcfs(im,x_fd,y_fd):用队列和集合记录遍历过的像素坐标代替单纯递归以解决cfs访问过深问题 # print(**********)xaxis[]yaxis[]visitedset()qQueue()q.put((x_fd,y_fd))visited.add((x_fd,y_fd))offsets[(1,0),(0,1),(-1,0),(0,-1)]#四邻域whilenotq.empty():x,yq.get()forxoffset,yoffsetinoffsets:x_neighbor,y_neighborxxoffset,yyoffsetif(x_neighbor,y_neighbor)in(visited):continue# 已经访问过了visited.add((x_neighbor,y_neighbor))try:ifim[x_neighbor,y_neighbor]0:xaxis.append(x_neighbor)yaxis.append(y_neighbor)q.put((x_neighbor,y_neighbor))exceptIndexError:pass# print(xaxis)if(len(xaxis)0|len(yaxis)0):xmaxx_fd1xminx_fd ymaxy_fd1yminy_fdelse:xmaxmax(xaxis)xminmin(xaxis)ymaxmax(yaxis)yminmin(yaxis)#ymin,ymaxsort(yaxis)returnymax,ymin,xmax,xmindefdetectFgPix(im,xmax):搜索区块起点 h,wim.shape[:2]fory_fdinrange(xmax1,w):forx_fdinrange(h):ifim[x_fd,y_fd]0:returnx_fd,y_fddefCFS(im):切割字符位置 zoneL[]#各区块长度L列表zoneWB[]#各区块的X轴[起始终点]列表zoneHB[]#各区块的Y轴[起始终点]列表xmax0#上一区块结束黑点横坐标,这里是初始化foriinrange(10):try:x_fd,y_fddetectFgPix(im,xmax)# print(y_fd,x_fd)xmax,xmin,ymax,ymincfs(im,x_fd,y_fd)Lxmax-xmin Hymax-ymin zoneL.append(L)zoneWB.append([xmin,xmax])zoneHB.append([ymin,ymax])exceptTypeError:returnzoneL,zoneWB,zoneHBreturnzoneL,zoneWB,zoneHB切割粘连字符代码defcutting_img(im,im_position,img,xoffset1,yoffset1):filename./out_img/img.split(.)[0]# 识别出的字符个数im_numberlen(im_position[1])# 切割字符foriinrange(im_number):im_start_Xim_position[1][i][0]-xoffset im_end_Xim_position[1][i][1]xoffset im_start_Yim_position[2][i][0]-yoffset im_end_Yim_position[2][i][1]yoffset croppedim[im_start_Y:im_end_Y,im_start_X:im_end_X]cv2.imwrite(filename-cutting-str(i).jpg,cropped)效果3.5 识别识别用的是typesseract库主要识别一行字符和单个字符时的参数设置识别中英文的参数设置代码很简单就一行我这里大多是filter文件的操作# 识别验证码cutting_img_num0forfileinos.listdir(./out_img):str_imgiffnmatch(file,%s-cutting-*.jpg%img_name.split(.)[0]):cutting_img_num1foriinrange(cutting_img_num):try:file./out_img/%s-cutting-%s.jpg%(img_name.split(.)[0],i)# 识别字符str_imgstr_imgimage_to_string(Image.open(file),langeng,config-psm 10)#单个字符是10一行文本是7exceptExceptionaserr:passprint(切图%s%cutting_img_num)print(识别为%s%str_img)最后这种粘连字符的识别率是在30%左右而且这种只是处理两个字符粘连如果有两个以上的字符粘连还不能识别但是根据字符宽度判别的话也不难有兴趣的可以试一下无需切割字符识别的效果需要切割字符的识别效果3.6 深度学习的验证码识别python库 tensorflow opencv, pandas gpu机器。训练集 10w 图片, 200step左右开始收敛。策略 切分图片训练单字母识别。预测时也是同样切分。ps:不切分训练及识别跑了一夜没有收敛准确率 在区分大小写的情况下单字母识别率98% 整体识别率75%。数据集数据集预处理package com;importjava.awt.Color;importjava.io.File;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.OutputStream;importjava.util.Random;importorg.patchca.color.ColorFactory;importorg.patchca.filter.predefined.CurvesRippleFilterFactory;importorg.patchca.filter.predefined.DiffuseRippleFilterFactory;importorg.patchca.filter.predefined.DoubleRippleFilterFactory;importorg.patchca.filter.predefined.MarbleRippleFilterFactory;importorg.patchca.filter.predefined.WobbleRippleFilterFactory;importorg.patchca.service.ConfigurableCaptchaService;importorg.patchca.utils.encoder.EncoderHelper;importorg.patchca.word.RandomWordFactory;publicclassCreatePatcha{private static Random randomnew Random();private static ConfigurableCaptchaService csnew ConfigurableCaptchaService();static{//cs.setColorFactory(new SingleColorFactory(new Color(25,60,170)));cs.setColorFactory(new ColorFactory(){Overridepublic Color getColor(intx){int[]cnewint[3];intirandom.nextInt(c.length);for(intfi0;fic.length;fi){if(fii){c[fi]random.nextInt(71);}else{c[fi]random.nextInt(256);}}returnnew Color(c[0],c[1],c[2]);}});RandomWordFactory wfnew RandomWordFactory();//wf.setCharacters(23456789abcdefghigklmnpqrstuvwxyzABCDEFGHIGKLMNPQRSTUVWXYZ);wf.setCharacters(0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ);wf.setMaxLength(4);wf.setMinLength(4);cs.setWordFactory(wf);}public static void main(String[]args)throws IOException{for(inti0;i100;i){switch(random.nextInt(5)){case0:cs.setFilterFactory(new CurvesRippleFilterFactory(cs.getColorFactory()));break;case1:cs.setFilterFactory(new MarbleRippleFilterFactory());break;case2:cs.setFilterFactory(new DoubleRippleFilterFactory());break;case3:cs.setFilterFactory(new WobbleRippleFilterFactory());break;case4:cs.setFilterFactory(new DiffuseRippleFilterFactory());break;}OutputStream outnew FileOutputStream(new File(i.png));String tokenEncoderHelper.getChallangeAndWriteImage(cs,png,out);out.close();File fnew File(i.png);f.renameTo(new File(checkdata/token_i.png));System.out.println(i验证码token);}}}训练篇幅有限更多详细设计见设计论文4 最后项目包含内容完整详细设计论文 项目分享:见文末!