相信做某本地生活平台网站爬虫的同学,饱受手势验证码的困扰,这类验证码相比滑块验证码,识别难度更大。
原始图片.png
看到这种验证码,你是否第一反应是想到打码平台?其实这种验证码我们也是可以尝试自己去crack的。本文不涉及模型原理,只涉及解决问题的方法,有兴趣的同学可以读一下何恺文大神的paper MaskRCNN
解决问题的思路
- 识别出轨迹的区域
- 对识别出来的区域进行骨架提取
- 对提取的中心线进行抽稀
- js模拟进行滑动轨迹(不在本文的讨论范围)
上干货
-
如何进行区域的识别呢?其实这是图像分割的一个典型应用,我们先采集验证码,使用labelme打标签,
标签后的图片.png -
数据预处理
- 由于这类图像分割对色值不敏感的,所以将rgb图像转换成灰度图像。(题主踩过坑,用rgb图像效果要差于灰度图像的)
-
图像对比度增强
预处理后的图片.png
-
使用MaskRCNN模型对处理后的图片进行训练,训练集用了100张图片,验证集用了14张图片,使用GPU训练的话速度还是挺快的,我尝试用了epoch为100,steps为1000,最终会训练100个模型
image.png
可以看到,在epoch为30左右就基本收敛了,在第48轮的时候出现了最小的loss 0.0252,所以我最终进行预测的模型就使用第48个模型
-
图像预测
模型在predict的时候,会返回mask,这个mask是与图像的尺寸大小一致的一个布尔矩阵,我们将mask为True的部分设置为白色,背景使用黑色进行图像二值化,输出的图像如下
image.png
是不是感觉离我们最终的结果更近一步了呢?
-
骨架提取
直接使用skimage的api,调包他不香吗?
image.png -
“冒尖点”处理
由于词库有限,暂且命名为冒尖点吧,这个冒尖点是因为预测出来的结果有锯齿,在骨骼提取的时候会有一些冒尖的点
消除前.png
消除后.png
这个线看着是不是离我们更近一步了呢?
-
线的抽稀
上一步处理好的点太多,我们需要尽可能保留线的形状,且减少尽可能多的点,使用dp算法可以进行线的抽稀,其实dp算法很简单,有兴趣可以看一下dp算法
抽稀后.png
是不是有模有样了??
- 模型评估
- 效率
我们公司的服务器GPU比较一般,只有4G显存,加载模型大概需要12s左右,预测第一张图片会比较慢,大约在6s左右,后续每张图片的预测及后续处理大概在800毫秒左右,也算是可接受 - ap@50:0.857
- 效率
总结
- 刚开始拿到这个任务的时候, 内心是崩溃的,因为从来没有搞过cv领域,后来理清思路后其实这事也没有想象中那么难
- 讲真,模型原理至今也没搞懂,更不用提如何优化他。
ps 代码已经上传到GitHub
了,有兴趣的可以翻看下,记得star哦