python 关于GMU官网验证码的识别(附详细过程)

2024-01-15 08:59

本文主要是介绍python 关于GMU官网验证码的识别(附详细过程),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、开发环境与所需的库

-开发环境: python 3.8
-库:PIL,matplotlib.pyplot,sklearn,opencv等
-编译器:pycharm

二、爬取需要识别图片

1.获得想要爬取验证码的网址
在这里插入图片描述(由此图片给出的信息,由此可以判断,想要的验证码的图片需要发起请求的网址)

2.爬取图片

url = "http://117.21.221.123/gnyxy/other/CheckCode.aspx"#需要发起请求的网址header = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1;Win64;x64;rv:81.0) Gecko/20100101 Firefox/81.0","Cookie": "ASP.NET_SessionId=mzmcjd45dyhbow55al3w4xmm; rootPath=http://117.21.221.123/gnyxy","Referer": "http://117.21.221.123/gnyxy/"}#设置请求头response = requests.get(url=url, headers=header).content#获得响应内容with open(path, 'wb')as fp:fp.write(response)#将图片保存至指定路径下

这样就就能批量获得验证码了

三、验证码的加工与修饰

之前爬取的验证码有大量的干扰线与干扰点,并且验证码颜色较为复杂,所以需要对图片进行加工
在这里插入图片描述
(类似图片)

1.灰度化处理
实现代码:

lim = image.convert('L')pixdata = lim.load()#创建一个二维列表存放图片每个像素的RGB值

或者

im = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

2.二值化处理
实现代码:

 w, h = lim.size#此处lim指的是灰度处理后图片对象# 遍历所有像素,大于阈值的为黑色for y in range(h):for x in range(w):if pixdata[x, y] < threshold:#threshold指的是一定阈值pixdata[x, y] = 0#将像素改为黑色else:pixdata[x, y] = 255

(或者)

lim = lim.point(lambda x: 255 if x > 134 else 0)

因为只是进行简单灰度处理,所以导致图片还有大量的干扰点与干扰线,会导致出现下面图片类似的情况
在这里插入图片描述
3. 降噪
原理:
降噪当前已经有了较好的算法能处理此类问题--------洪水填充法 洪水填充法洪水填充法分为四邻域与八邻域算法。笔者在这里使用的是八邻域算法。

实现代码:

    for i in range(0, Z):pixdata[0, 0] = 255  # 将左顶点改为白色色块pixdata[(image.size[0] - 1, image.size[1] - 1)] = 255  # 将右脚点改为白色模块for x in range(1, image.size[0] - 1):for y in range(1, image.size[1] - 1):nearDots = 0L = pixdata[x, y]  # 获去该坐标的颜色RGB是否是1还是0# 用的是八领域算法if L == pixdata[x - 1, y - 1]:nearDots += 1if L == pixdata[x - 1, y]:nearDots += 1if L == pixdata[x - 1, y + 1]:nearDots += 1if L == pixdata[x, y - 1]:nearDots += 1if L == pixdata[x, y + 1]:nearDots += 1if L == pixdata[x + 1, y - 1]:nearDots += 1if L == pixdata[x + 1, y]:nearDots += 1if L == pixdata[x + 1, y + 1]:nearDots += 1if nearDots < N:  # 有四个相邻的点与该点的颜色是一样的pixdata[x, y] = 255  # 判断如果有的话,将其变为白点

效果图如下在这里插入图片描述
(图片处理好了,可是为了简化对象,所以我们需要将图片进行分割)

四、图片的分割

原理:通过再次加载图片,获取每一个像素点的颜色RGB是1还是0。通过起始寻找上下左右,是否有黑色的像素点。如果有则寻找该像素点的前后左右是否黑色像素点,以此类推,直至找不到黑色点,则为该字符的边界。

实现代码

def get_crop_imgs(im,num,path,pixdata):zoneWB = CFS(im,pixdata)# print(zoneWB)cutting_img(im,num,path,zoneWB)def CFS(im,pixdata):'''切割字符位置'''xmax = 0  # 上一区块结束黑点横坐标,这里是初始化zoneWB = []  # 各区块的X轴[起始,终点]列表for i in range(4):try:# print(xmax)x_fd,y_fd = detectFgPix(im,xmax,pixdata)# print(y_fd,x_fd)xmax,xmin=cfs(x_fd,y_fd,pixdata)# if(xmax>20):#     xmax //= 2zoneWB.append([xmin,xmax])except TypeError:return zoneWBreturn zoneWB
def detectFgPix(im,xmax,pixdata):'''搜索区块起点'''h = im.size[1]w = im.size[0]for x_fd in range(xmax+1,w):for y_fd in range(h):if pixdata[x_fd,y_fd] == 0:return x_fd,y_fddef cfs(x_fd,y_fd,pixdata):'''用队列和集合记录遍历过的像素坐标代替单纯递归以解决cfs访问过深问题'''# print('**********')xaxis=[]visited = set()q = Queue()q.put((x_fd, y_fd))visited.add((x_fd, y_fd))offsets=[(1, 0), (0, 1) ,(-1, 0), (0, -1)]#四邻域while not q.empty():x,y=q.get()for xoffset,yoffset in offsets:x_neighbor = x+xoffsety_neighbor = y+yoffsetif (x_neighbor,y_neighbor) in (visited):continue  # 已经访问过了else:visited.add((x_neighbor, y_neighbor))try:if pixdata[x_neighbor, y_neighbor] == 0:xaxis.append(x_neighbor)q.put((x_neighbor,y_neighbor))except IndexError:pass# print(xaxis)if (len(xaxis) == 0 ):xmax = x_fd + 1xmin = x_fdelse:xmax = max(xaxis)xmin = min(xaxis)#ymin,ymax=sort(yaxis)return xmax,xmindef cutting_img(img,num,path,zoneWB):img_arr = plt.imread(path)for i in range(4):image_child_name = str(num)+'_'+str(i)+'.jpg'image_path='D://idcodes/' + image_child_namex_min_postion = zoneWB[i][0] - 1x_max_postion = zoneWB[i][1] +1cropped = img_arr[0:22,x_min_postion:x_max_postion]#获取需要剪切图片的位置cv2.imwrite(image_path,cropped)# tuple_child = (x_min_postion,0,x_max_postion,22)#进行图片的切割,并保存到指定路径下# plt.savefig(image_path)# img = img.crop(tuple_child)# img.save(image_path)if os.path.exists(path):os.remove(path)else:print('未找到此文件')

在这里插入图片描述在这里插入图片描述
分割之后出现类似的图片表示成功了

五、模型的训练

我在这里运用的是knn算法(分类算法)对验证码的每个字符进行识别以及分类

易错点:因为图片大小不同,所以运用 cv2.imread获取的数据的shape是不同的,所以不能将不同大小的图片作为同一个训练集使用,因为上述分割算法,分出来的图片大小是不一的。所以knn算法是不行的吗?

解决方法
1.将所有的图片转化为统一大小

img_ls=["2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","J","K","L","M","N","P","Q","R","S","T","U","W","X","Y","Z"]
for name in img_ls:data_width = []path = os.path.join(img_path, name)# print(path)img_names = os.listdir(path)for i in range(len(img_names)):path1 = os.path.join(path, img_names[i])img = Image.open(path1)type = "png"out = img.resize((13, 22), Image.ANTIALIAS)# # resize image with high-qualityos.remove(path1)out.save(path1, type)

2.分别获得数据的目标值和特征值

data_sum = []labels = []img_path = "D:\img_src"img_ls = os.listdir(img_path)for name in img_ls:path = os.path.join(img_path,name)# print(path)img_names =os.listdir(path)for i in range(len(img_names)):path1 = os.path.join(path,img_names[i])image = cv2.imread(path1)image = image.reshape(-1)#将数据转化为一维数组data_sum.append(image)#提供特征值labels.append(name)#提供目标值

3.将特征值和目标值数组化并分化成训练集和测试集:

 	y = LabelBinarizer().fit_transform(labels)#标签规范化x = np.array(data_sum,dtype=object)y = np.array(y)x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)

4.训练模型:

 # 训练KNN分类器model = neighbors.KNeighborsClassifier()model.fit(x_train, y_train)

5.测试并保存模型

 dirs = 'D:/testModel'if not os.path.exists(dirs):os.makedirs(dirs)joblib.dump(model,dirs + '/LR.pkl')#测试结果打印pre_y_train = model.predict(x_train)pre_y_test = model.predict(x_test)class_name = [ 'class2', 'class3', 'class4', 'class5', 'class6', 'class7', 'class8', 'class9',         'classa','classb','classc','classd','classe','classf','classg','classh','classj','classk','classl','classm','classn','classp','classq', 'classr','classs','classt','classu','classw','classx','classy','classz']print(classification_report(y_train, pre_y_train, target_names=class_name))print(classification_report(y_test, pre_y_test, target_names=class_name))

6.结果截图

改进方法:可以利用网格搜索与交叉验证提高准确率

通过这几个步骤就能得到比较准确的模型了

这篇关于python 关于GMU官网验证码的识别(附详细过程)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/608349

相关文章

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

作业提交过程之HDFSMapReduce

作业提交全过程详解 (1)作业提交 第1步:Client调用job.waitForCompletion方法,向整个集群提交MapReduce作业。 第2步:Client向RM申请一个作业id。 第3步:RM给Client返回该job资源的提交路径和作业id。 第4步:Client提交jar包、切片信息和配置文件到指定的资源提交路径。 第5步:Client提交完资源后,向RM申请运行MrAp

阿里开源语音识别SenseVoiceWindows环境部署

SenseVoice介绍 SenseVoice 专注于高精度多语言语音识别、情感辨识和音频事件检测多语言识别: 采用超过 40 万小时数据训练,支持超过 50 种语言,识别效果上优于 Whisper 模型。富文本识别:具备优秀的情感识别,能够在测试数据上达到和超过目前最佳情感识别模型的效果。支持声音事件检测能力,支持音乐、掌声、笑声、哭声、咳嗽、喷嚏等多种常见人机交互事件进行检测。高效推

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

nudepy,一个有趣的 Python 库!

更多资料获取 📚 个人网站:ipengtao.com 大家好,今天为大家分享一个有趣的 Python 库 - nudepy。 Github地址:https://github.com/hhatto/nude.py 在图像处理和计算机视觉应用中,检测图像中的不适当内容(例如裸露图像)是一个重要的任务。nudepy 是一个基于 Python 的库,专门用于检测图像中的不适当内容。该

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip

HTML提交表单给python

python 代码 from flask import Flask, request, render_template, redirect, url_forapp = Flask(__name__)@app.route('/')def form():# 渲染表单页面return render_template('./index.html')@app.route('/submit_form',