准备工作
因为本节主要是说 识别验证码缺口的流程,所以对于涉及深度学习的代码需要下载
https://github.com/Python3WebSpider/DeepLearningSlideCaptcha2
然后切换到刚刚下载的目录 DeepLearningSlideCaptcha2
安装必要的依赖库,这里有两个库是指定了版本的,如果安装不上,就手动安装最新版本的
pip install -r requirements.txt
目标检测
目标检测:顾名思义就是把想要找的东西找出来
现在比较流行的算法有: R-CNN FastR-CNN , FasterR-CNN, SSD , YOLO 等
目前目标算法主要有两种实现方法----一阶段式和两阶段式, 英文名叫做: One Stage 和 Two Stage
One Stage : 不需要生产候选框, 直接将目标的定位和分类问题转化为回归问题,俗称 “看一眼” ,使用这种算法的有 YOLO 和 SSD ,这种算法虽然正确率不及 Two Stage ,但架构相对简单,检测速度快
Two Stage: 算法首先要生成一系列目标所在位置的候选框, 再对这些框选出来的结果进行样本分类,即先找出来在哪, 再分出来是啥, 俗称 “看两眼” 使用这种实现的算法有 R-CNN , Fast R -CNN , Faster R - CNN 等, 这种方法架构相对复杂, 但正确率高
这里我们选用 YOLO 算法实现对滑动验证码缺口的识别。 YOLO 的英文全称是: You Only Look Once , 目前最新版本是 V5, 应用比较广泛的版本是 V3 , 具体的可以自行学习
数据准备
数据分为两部分, 一部分是验证码图片,一部分是数据标注。数据标注是缺口位置,缺口对应一个矩形框, 要表示矩形框,至少需要 4 个数据, 如矩形框左上角的点的横纵坐标 x, y 加上矩形的宽高 w, h
明确了数据是什么, 接下来就着手准备。第一步是收集验证码图片,第二步是标注图片中缺口位置并转化为想要的 4 位数字。 打开网站 https://captcha1.scrape.center/ 点击登录,就会出现一个滑动验证码
那么接下来就是保存图片了。前面下载的代码中就有这脚本
collect.py
from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import WebDriverException import time from loguru import logger COUNT = 1000 for i in range(0, COUNT + 1): try: browser = webdriver.Chrome() wait = WebDriverWait(browser, 10) browser.get('https://captcha1.scrape.center/') button = wait.until(EC.element_to_be_clickable( (By.CSS_SELECTOR, '.el-button'))) button.click() captcha = wait.until( EC.presence_of_element_located((By.CSS_SELECTOR, '.geetest_slicebg.geetest_absolute'))) time.sleep(5) captcha.screenshot(f'data/captcha/images/captcha_{i}.png') except WebDriverException as e: logger.error(f'webdriver error occurred {e.msg}') finally: browser.close()
如果有什么没有包没有的,自行安装
代码中先是一个 for 循环, 循环次数为 COUNT , 每次循环都使用 Selenium 启动一个浏览器,然后打开目标网站,模拟点击“登录”按钮的操作触发验证码的弹出,然后截图验证码对应的节点,在调用 screenshot 方法保存下来
运行 collect.py 后 data/captcha/images 目录下就会出现很多验证码图片,这样第一步就完成了
接下来第二步,数据标注,这里推荐使用工具 labelImag , 下载地址
https://github.com/tzutalin/labelImg 使用 pip 安装
如果有 Anaconda 就使用 conda 没有就使用 pip 都可以
1. 打开 cmd 或者 Anaconda Prompt
2. 进入自己要安装的环境
3. 输入: pip install labelimg -i https://pypi.tuna.tsinghua.edu.cn/simple
4 , 安装完成之后, 输入 labelimg 即可打开对应的界面
点击左侧的 Open Dir 按钮打开 data/captcha/images 目录,然后点击 更多(朝下的双箭头)
找到 Create RectBox 创建一个标注框,可以将缺口所在的位置框起来, 然后 labelImg 就会弹出填写保存名称的提示框,填写 taget , 然后点击 ok 这时就会发现本地保存了一个 xml 文件
如果标注的时候闪退,有可能是python 版本太高的原因 例如 python 11
从中可以看到 size 中有三个节点,分别是 width, height j 和 depth ,代表源验证码的 宽, 高, 通道数。 object 节点的 bndbox 节点包含标注的缺口位置, 通过观察对比可以知道 xmin , ymin 是指 左上角的坐标, xmax, ymax 是指右下角的坐标
我们可以使用下面的方法做一些处理
import xmltodict import json def parse_xml(file): xml_str = open(file, encoding='utf-8').read() data = xmltodict.parse(xml_str) data = json.loads(json.dumps(data)) annoatation = data.get('annotation') width = int(annoatation.get('size').get('width')) height = int(annoatation.get('size').get('height')) bndbox = annoatation.get('object').get('bndbox') box_xmin = int(bndbox.get('xmin')) box_xmax = int(bndbox.get('xmax')) box_ymin = int(bndbox.get('ymin')) box_ymax = int(bndbox.get('ymax')) box_width = (box_xmax - box_xmin) / width box_height = (box_ymax - box_ymin) / height return box_xmin / width, box_ymax / height, box_width / width, box_height / height
这里定义了一个 parse_xml 方法, 这个方法首先读取 xml 文件, 然后调用 xmltodict 库里的 parse 方法将 XML 字符串转换为 JSON 字符, 之后依次读取验证码的 宽高信息和缺口位置信息,最后以元组的形式返回我们想要的数据-----缺口左上角点的坐标和宽高的相对值。都标注好后,对每个 xml 文件都调用一次此方法便可以生成想要的标注结果了
这里已经有标注好的对应的结果了,在这里可以直接使用,结果保存路径为 data/captcha/labels, 其中每个 txt 文件对应一张验证码图片的标注结果,文件内容类似这样
0 0.6153846153846154 0.275 0.16596774 0.24170968
第一个 0 代表标注目标的索引, 由于我们只需要检测一个缺口,所以索引就是 0 ; 第二位和第三位代表左上角缺口的点在验证码图片中所处的位置,例如 0.6153846153846154 代表从横向上看,缺口左上角的点大约位于验证码的 61.5% 处, 这个值乘上验证码的宽度 520 得到 320 , 表示从左上角的点的偏移量是 320 像素。第四位和第五位代表缺口的宽高和验证码图片的宽高比,例如用第五位的 0.24170968 乘以验证码图片的高度 320 得到大约 77 , 表示缺口的高度大约为 77 像素
至此数据准备阶段完成
训练
为了达到更好的效果,还需要下载一些预训练模型, 预训练的意思就是已经有一个提起那训练好的基础模型了,直接使用预训练模型中的权重文件,就不需要从零开始训练了, 只需要基于之前的模型进行微调就好了 ,这样即节省时间又能达到比较好的效果
先下载预训练模型, YOLO V3 模型能有不错的训练效果,下载预训练模型的命令如下
bash prepare.sh
注意: 在windows 环境下, 使用 Bash 命令行工具 (如 Git Bash)运行此命令
之后,就能下载 YOLO V3 模型的一些权重文件, 包括 yolov3.weights 和 darknet.weights 在正式训练之前,需要使用这些权重文件初始化 YOLO V3 模型
接下来就是训练了,推荐使用 GPU 来训练,运行命令如下
bash train.sh
注意: 在windows 环境下, 使用 Bash 命令行工具 (如 Git Bash)运行此命令
在训练过程中我们可以使用 TensorBoard 观察 loss 和 mAP 变化, 运行命令如下
tensorboard --logdir='logs' --port=6006 --host 0.0.0.0
注意: 请确保已经正确安装了本项目的所有依赖库,其中就包括 TensorBoard ,安装之后便可以使用 tensorboard 命令
运行后打开 http://localhost:6006观察 loss 和 mAP 的变化图
可以看到 loss 最初非常高,之后会慢慢下降,正确率逐渐接近 100%
测试
模型训练完毕后,会在 checkpoints 文件中生成一些 pth 文件,这些就是模型文件,我们可以直接使用这些模型做测试,生成标注结果
现在测试文件夹 data/captcha/test 下放入一些验证码图片
运行如下命令
bash detect.sh
该命令会读取测试文件下的所有图片, 并将处理后的结果输出到 data/captcha/result 文件夹,控制台输出一些验证码的识别结果, 同时, 在 data/captcha/result 文件夹下会生成标注结果
实际上 detect.sh 命令的作用是运行 detect.py 文件
总结: 这里涉及了深度学习,还会因为各个库的版本问题,例如 python 导致有些地方的运行不顺,或者实现的结果不同,这些都不是主要,主要的了解整个流程