使用MaskRCNN进行手势验证码识别

相信做某本地生活平台网站爬虫的同学,饱受手势验证码的困扰,这类验证码相比滑块验证码,识别难度更大。


原始图片.png

看到这种验证码,你是否第一反应是想到打码平台?其实这种验证码我们也是可以尝试自己去crack的。本文不涉及模型原理,只涉及解决问题的方法,有兴趣的同学可以读一下何恺文大神的paper MaskRCNN

解决问题的思路

  1. 识别出轨迹的区域
  2. 对识别出来的区域进行骨架提取
  3. 对提取的中心线进行抽稀
  4. js模拟进行滑动轨迹(不在本文的讨论范围)

上干货

  • 如何进行区域的识别呢?其实这是图像分割的一个典型应用,我们先采集验证码,使用labelme打标签,


    标签后的图片.png
  • 数据预处理

    1. 由于这类图像分割对色值不敏感的,所以将rgb图像转换成灰度图像。(题主踩过坑,用rgb图像效果要差于灰度图像的)
    2. 图像对比度增强


      预处理后的图片.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

总结

  1. 刚开始拿到这个任务的时候, 内心是崩溃的,因为从来没有搞过cv领域,后来理清思路后其实这事也没有想象中那么难
  2. 讲真,模型原理至今也没搞懂,更不用提如何优化他。

ps 代码已经上传到GitHub
了,有兴趣的可以翻看下,记得star哦

你可能感兴趣的:(使用MaskRCNN进行手势验证码识别)