利用modelarts和物体检测方式识别验证码
近来有朋友让老山帮忙识别验证码。在github上查看了下,目前开源社区中主要流行以下几种验证码识别方式:
- tesseract-ocr模块:
这是HP实验室开发由Google 维护的开源 OCR引擎,内置传统模式识别方法和现代深度神经网络算法 - 采用深度学习网络
通常是基于CNN网络,通过captcha等验证码生产器自动生产训练集,通常对生成器内置的验证码类型有极高的识别度。
需求中需要识别的验证码来自特定网站 http://fota.redstone.net.cn/,使用通用的验证码识别模块识别准确率比较低,因此很可能需要自己创建数据集进行训练。
查看数据
无论如何,都必须看到数据才能处理数据。因此我们通过对网站进行请求生成验证码集:
import os, requests
from time import sleep
# 文件保存路径
path = 'images'
# 验证码网站
url = 'http://fota.redstone.net.cn/index.php/home/index/get_verify.html'
# 图片数目
number = 100
os.makedirs(path, exist_ok=True)
# 请求并保存图片
for i in range(number):
sleep(0.1)
r = requests.get(url)
with open(f'{path}/{i}.jpg', 'wb') as f:
f.write(r.content)
观察数据:
通过观察数据,发现这些验证码基本有这几个特点:
- 需要识别的是4个数字;
- 数字字体有多种风格,数字有一定旋转,数字之间有可能交叉;
- 背景中有许多小字;
- 与数字相同的颜色的间断粗线穿过数字,对数字识别造成影响。
标注
按通常的图像处理方式,可以通过形态学去除小字,然后转换成灰度图进行后期训练处理。但老山正好最近涉及些图像识别的深度学习方法,于是在想,是否能直接通过yolov3,faster-rcnn等物体检测模型来识别验证码呢?
要按物体检测方式识别验证码,首先要有标注数据集,这里采用modelarts内置的标注进行标注。
- 先将图像传到obs中
2. 在modelarts上点击创建数据集
3. 按要求填写列表,选择物体检测,(标签可以在此处添加,也可以在标注的时候添加),然后创建数据集
4. 点击进入已创建的数据集,然后就可以进行图片标注了
5. 这里不得不提的是智能标注,这也成为后面老山深深的怨念;在标注图片超过20的时候,就可以启用智能标注,可以自动识别物体,减少标注时间
运行10多分钟后,标注就完成了,可以看到,标注的效果是真好
在已标注集仅为20的情况下,虽然还有不少需要更改的地方,但效果还是可用的;但标注集达到100时,效果就可以达到95%以上的准确率;由于智能标注使用的算法无非是常见的物体检测方法的一种,如此好的效果让我一度产生“标注数据集100就可以得到很好的训练效果“的幻觉。
训练
1. 标注完成后,点击数据集右侧的发布按钮,然后你在数据集输出路径里很深的路径里找到生成的标注的xml文件
2. 如果需要追加待标注数据集,可以对输入位置对应的obs路径中添加图像,然后在标注页面里点击”同步数据源“
3. 第一期标注了200张已标注图片,于是老山自信满满的打开训练作业,创建了faster-rcnn的训练作业
话说训练作业不用写代码还是很方便的,尤其适合前期尝试模型,让大家对模型能达到的准确率做个初步的判断,避免在一个不适合的模型中花费太多的时间。
在目前物体检测中,faster-rcnn、yolov3还有retinanet都是比较主流的模型。先尝试了faster-rcnn,mAP值只有0.2,然后是yolov3,mAP是0.29,用了retinanet,mAP值到了0.58。
老山于是便有了怨念,智能标注用啥模型啊,不还得是主流目标检测模型吗,为什么标注20张图就能有如此高的准确率,老山200张图训练的模型效果都不如他。尤其是前面faster-rcnn和yolov3的mAP值都如此的低,让老山一度很灰心,还好retinanet的效果还不错,可以继续调×教。
虽然老山调不出智能标注使用的模型,但模型复制嘛,不只是复制模型一种方法而已,把模型的结果集作为老山模型的训练集,只要数量足够大,也可以训练出相近的模型。于是就一口气又生成了800张图片,然后用已标注的200张图片做智能标注。由于标注结果十分准确,大部分标注结果就直接确认了,标注了800张图片,只花了1个多小时,效率可以说是杠杠的!
然后使用这1000个样本的数据集杀了回来,mAP值达到了0.96!看来数据集的大小非常重要,这还只是用了默认参数。
在观察日志的时候,发现右上角有个修改,点进去发现可以基于训练模型基础继续训练,同时发现预制算法旁边有个算法详情,里面描述了算法的运行参数。考虑到上次运行早停了,看了一通参数的含义,最后只改了decay_patience这个参数。
又跑了一遍,这次mAP又小小的提高到了0.97!但这些都只是个摸不着的结果,老山决定部署下看下结果
先在训练作业结果中点击创建模型,把名称改成有意义的,其他参数保持不变就好,
部署
等待模型状态正常后,点击右边的部署
等到部署完成后,点击部署任务中的预测,并上传图片,查看结果
许多结果看起来还可以
但也有不少结果没有预测正确
为此统计下这1000张图片的预测结果(老山这里比较懒,并没有单独准备测试集),我们需要对这些图片进行预测。由于不可能人工上传预测,为此老山祭出了大杀器,python。
首先,我们要获取X-Auth-Token认证
import requests
import json
url = "https://iam.cn-north-1.myhuaweicloud.com/v3/auth/tokens"
headers = {"Content-Type":"application/json"}
data = {
"auth": {
"identity": {
"methods": ["password"],
"password": {
"user": {
"name": "your-username",
"password": "your-password",
"domain": {
"name": "your-domainname:normally equal to your-username"
}
}
}
},
"scope": {
"project": {
"name": "cn-north-1"
}
}
}
}
data = json.dumps(data)
r = requests.post(url, data = data, headers = headers)
print(r.headers['X-Subject-Token'])
data具体参数填写可网址详见https://support.huaweicloud.com/api-modelarts/modelarts_03_0004.html
程序最后获得的便是X-Auth-Token认证码。
接下来我们开始预测
config.py
X_Auth_Token = "MIIZpAYJKoZIhvcNAQcCoIIZlTCC..." # 前面获取的X-Auth-Token值
url = "https://39ae62200d7f439eaae44c7cabccf5de.apigw.cn-north-1.huaweicloud.com/v1/infers/55d5..." #在调用指南页面获取的url值
predict.py
import os
import json
from lxml import etree as ET
import requests
from config import url, X_Auth_Token
import logging
logging.basicConfig(level=logging.INFO,
format="%(asctime)s %(name)s %(levelname)s %(message)s",
handlers = [
logging.FileHandler(f"log.txt"), #生成日志文件
logging.StreamHandler()
])
# 图片(jpg文件)和标注文件(xml文件)所在位置,注意jpg和xml文件一一对应
path = 'images1000'
def requestImage(filename):
'''根据图片文件利用在线服务预测结果, jsonStr'''
files = {'images':open(filename,'rb')}
headers2 = {'X-Auth-Token': X_Auth_Token}
response = requests.request("POST", url, files=files, headers=headers2)
return response.text
def getImageFile(xml_file):
'''根据xml文件返回对应的图片文件'''
return os.path.splitext(xml_file)[0]+'.jpg'
def getFileList(folder):
'''folder下的同名xml和jpg组成tuple,并以list返回 [(xml_file, jpeg_file), ...]'''
return [(os.path.join(folder, filename), os.path.join(folder, getImageFile(filename))) for filename in os.listdir(folder) iffilename.endswith('.xml')]
def json2text(jsonStr):
'''根据预测结果jsonStr返回预测的数字'''
obj = json.loads(jsonStr)
boxes = []
for className, box in zip(obj["detection_classes"], obj["detection_boxes"]):
boxes.append([className]+[float(pos) for pos in box])
# 注意预测的box以[top, left, bottom, right]进行排序,与xml文件有点不同
boxes.sort(key = lambda x: x[2])
return ''.join([className for className, *_ in boxes])
def xml2text(xml_file):
'''根据xml_file里所有box生成list [(class_name, left, top, right, bottom), ...]'''
tree = ET.parse(xml_file)
root = tree.getroot()
boxes = []
for obj in root.findall('object'):
name = obj.find('name').text
xmlbox = obj.find('bndbox')
b = (round(float(xmlbox.find('xmin').text)), round(float(xmlbox.find('ymin').text)),
round(float(xmlbox.find('xmax').text)), round(float(xmlbox.find('ymax').text)))
boxes.append((name, *b))
boxes.sort(key = lambda x: x[1])
return ''.join([className for className, *_ in boxes])
if __name__ == "__main__":
fileList = getFileList(path)
count = 0 # 预测数目
sameCount = 0 # 预测正确数目
for xml_file, jpg_file in fileList:
# 根据图片文件在线预测结果
jsonStr = requestImage(jpg_file)
text_image = json2text(jsonStr)
# 根据标注文件获得正确结果
text_xml = xml2text(xml_file)
# 对比输出
count += 1
if text_image==text_xml:
sameCount+=1
logging.info(f"count:{count}, sameCount:{sameCount}, \
text_image:{text_image}, text_xml:{text_xml}, percent:{sameCount/count}")
运行程序结果如下
可以看到,由于在线服务使用的是CPU,预测的结果比较慢,大概5~6秒出一个结果,准确率一直不高,最后定格在75.6%。对于这个结果,老山只能说,还好是用于预测验证码,可以反复预测,预测正确的期望次数是1.3次,算是可堪一用把。
总结
当然,本文算是使用modelarts对使用物体检测算法来识别验证码做了个试探,总体结果说明这种识别验证码的方法完全是可以用的,如果后续需要继续进展的话,完全可以在以下方面进行展开:
- 数据集生成:
数据集仍可以继续扩大。此时就不需要在手动标注了,老山想到一个很好的办法。生成数据集后,用智能标注的方式生成标注结果,将标注结果利用网站去验证正确与否,这样就可以无需手动,生成很好的数据集,现在智能标注免费,完全是白嫖,数据集够大时,至少能达到智能标注的水平(无限怨念)。 - 模型参数调节
预置模型很省心,但却看不到细节,如果想自己把握模型,可以使用开源模型来运行,老老实实的写代码调参数。如果没有GPU环境,可以使用开发环境的notebook进行开发;
3. 在本地开启服务
用在线服务功能当然省心,但如果只是为了识别验证码,这性价比就不是太高了。我们可以在预置模型的输出路径找到模型生成文件,这样就可以把模型布置在本地了。
作者:山找海味
利用modelarts和物体检测方式识别验证码的更多相关文章
- OpenCV学习 物体检测 人脸识别 填充颜色
介绍 OpenCV是开源计算机视觉和机器学习库.包含成千上万优化过的算法.项目地址:http://opencv.org/about.html.官方文档:http://docs.opencv.org/m ...
- 人脸检测及识别python实现系列(5)——利用keras库训练人脸识别模型
人脸检测及识别python实现系列(5)——利用keras库训练人脸识别模型 经过前面稍显罗嗦的准备工作,现在,我们终于可以尝试训练我们自己的卷积神经网络模型了.CNN擅长图像处理,keras库的te ...
- 如何利用AI识别未知——加入未知类(不太靠谱),检测待识别数据和已知样本数据的匹配程度(例如使用CNN降维,再用knn类似距离来实现),将问题转化为特征搜索问题而非决策问题,使用HTM算法(记忆+模式匹配预测就是智能),GAN异常检测,RBF
https://www.researchgate.net/post/How_to_determine_unknown_class_using_neural_network 里面有讨论,说是用rbf神经 ...
- [Xcode 实际操作]七、文件与数据-(20)CoreML机器学习框架:检测和识别图片中的物体
目录:[Swift]Xcode实际操作 本文将演示机器学习框架的使用,实现对图片中物体的检测和识别. 首先访问苹果开发者网站关于机器学习的网址: https://developer.apple.com ...
- 利用opencv进行移动物体检测
进行运动物体检测就是将动态的前景从静态的背景中分离出来.将当前画面与假设是静态背景进行比较发现有明显的变化的区域,就可以认为该区域出现移动的物体.在实际情况中由于光照阴影等因素干扰比较大,通过像素直接 ...
- 第十八节、基于传统图像处理的目标检测与识别(HOG+SVM附代码)
其实在深度学习中我们已经介绍了目标检测和目标识别的概念.为了照顾一些没有学过深度学习的童鞋,这里我重新说明一次:目标检测是用来确定图像上某个区域是否有我们要识别的对象,目标识别是用来判断图片上这个对象 ...
- 物体检测之FPN及Mask R-CNN
对比目前科研届普遍喜欢把问题搞复杂,通过复杂的算法尽量把审稿人搞蒙从而提高论文的接受率的思想,无论是著名的残差网络还是这篇Mask R-CNN,大神的论文尽量遵循著名的奥卡姆剃刀原理:即在所有能解决问 ...
- yolo回归型的物体检测
本弱又搬了另外一个博客的讲解: 缩进YOLO全称You Only Look Once: Unified, Real-Time Object Detection,是在CVPR2016提出的一种目标检测算 ...
- 转-------基于R-CNN的物体检测
基于R-CNN的物体检测 原文地址:http://blog.csdn.net/hjimce/article/details/50187029 作者:hjimce 一.相关理论 本篇博文主要讲解2014 ...
随机推荐
- 《STL源码剖析》——List
List list位于头文件<<stl_list.h>>中 list是sequence containers中的一种 1 List的基本架构 list的基本结构的UML关系图如 ...
- 通过ISO镜像简单搭建本地yum仓库
本文参考链接:https://segmentfault.com/a/1190000015155966 *有时候在我们本地搭建一些Linux上的程序运行环境或者安装一些软件的时候,难免会遇到需要使用yu ...
- Codeforces Round #599 (Div. 2) E. Sum Balance
这题写起来真的有点麻烦,按照官方题解的写法 先建图,然后求强连通分量,然后判断掉不符合条件的换 最后做dp转移即可 虽然看起来复杂度很高,但是n只有15,所以问题不大 #include <ios ...
- 爬虫之request库主要解析---参照慕课北理工嵩天
kv = {'key1':'value1','key2':'value2'} r = requests.request (' GET' , 'http://python123.io/ws' , par ...
- 创建windows系统下的虚拟机
创建新的虚拟机 添加映像(windows系统下必须先添加映像) 选择相应的镜像文件:网上查找密钥输入:版本按要求选择:单击 下一步:设置虚拟机名称 位置 :下一步 默认的磁盘大小(不用管)——下一 ...
- dhcpv6+radvd服务器搭建
1.isc-dhcp-server install sudo apt update sudo apt-get install isc-dhcp-server 2.设置dhcp 创建/etc/dhcp/ ...
- PHP结合SQL语句写一句话木马
一.基础类的一句话--功能仅限于验证漏洞了,实际中太容易被查出出来: 1 <?php @eval($_GET["code"])?> 2 <?php @system ...
- Linux跨网段通信小实验
一.实验场景. 实验准备,Linux主机4台.分别是主机A,路由主机R1,路由主机R2,主机 C,主机A的ip是192.168.56.66/24,且只有一块网卡eth0:路由主机R1有两块网卡eth0 ...
- xilinx FPGA全局时钟资源的使用
1.什么是xilinx fpga全局时钟资源 时钟对于一个系统的作用不言而喻,就像人体的心脏一样,如果系统时钟的抖动.延迟.偏移过大,会导致系统的工作频率降低,严重时甚至会导致系统的时序错乱,实现不了 ...
- nuxt遇到的问题(一)window 或 document is not defined
因为用了VUE做的官网,既然是官网了避免不了SEO的问题了(该死当初就不应该选择用vue) 很自然就是选择了使用nuxt.js来做ssr预渲染了. 因为网站不是响应式的,PC / 移动端要进行对应跳转 ...