滑动验证码

万圣节那天下班回家在地铁口碰到公司一全栈高手(前端人员写CS结构程序),当然自然而然就顺便聊了一下技术,期间就说到了滑动验证码,首先声明我不是做计算机图形的,只是以前做过简单的验证码识别和远控,都是基于图像处理的,可以说对于图像处理我只会点皮毛,和一点基础算法吧。当时听同事稍微了说了下感觉有一定的难度,还听说公司里面有一个“同事”用python写成了开源组件,在这给大佬们点个大大的赞。可惜就只聊了那么几分钟吧,同事到站了,就留我一个人在地铁上看着抖音。
晚上回到家想了下,决定试试,打开浏览器访问京东官网,通过DOM元素简单的看了下京东的滑动验证码。无独有偶恰巧周六小孩学校活动爬山,孩子她妈问我去不去,我想了下,当时就果断决定了不去,心里在想明天好好码一天code,看能不能解决滑动验证码识别的问题。
第二天一大早起来,坐电脑旁边巴拉巴拉了一堆代码,不用说大家应该知道,就是采用一些基础算法把彩色绚丽的原图灰度化、二值化、降糙等等。求灰度值有专门的公式,不需要我们补脑RGB三元组,二值化也很简单,所谓二值就是0 1,不是黑就是白,但是需要自己结合图片设定阈值。非专业的话,还是建议做图片处理的朋友,首先还是先了解熟悉Color ARGB BitMap位图 像素 位深 跨距 PNG JPG等等,百度一堆。下面看看我这边处理的效果。
基本处理
原图:
灰度化:
二值化:
可能中间还有去糙的操作,结合实际情况吧,这些基础的图像处理,其实很简单。二值化之后,图片上红色箭头部分就是我要找的部分,怎么找呢?其实就算是横竖遍历时间复杂度也还好,因为图片像素小啊,指针处理法还是很快的(主要这种遍历横竖不适合)。具体怎么找,这里我简单说下我的见解,对于我们这些不是做图形学的朋友来说,看到这么一张图片如果按照程序的逻辑去思考还真比较呆板和麻烦。那怎么办?我的处理方式,站在我的角度,我眼睛识别的角度,我眼睛看到哪个区域再传给我大脑比较,如果不是再随机扫这幅图片的另外一个区域。说的很简单,那么问题来了,代码怎么写?这个算法怎么写?
查找我先说下我第一种吧
1.对这副图片随机撒点1000个,具体多少个结合图片像素大小吧,然后遍历这1000个点,如果这个点的颜色值&255=255,我就向左边扫描,直到不能扫为止,也就是色块不同,然后沿周边扫描,最后发现逻辑不好控制,如果被扫图片部分非常不规整和复杂的话,覆盖率不是很可观,果断放弃,考虑另外一种方法。
2.对这副图片随机撒点1000个,然后遍历这1000个点,如果这个点的颜色值&255=255,那么一这个点为中心形成类似九宫格的排列,向4周8个像素点扩散,直到每个像素点不能扩散为止,也就是色块值不同了,这种做法代码简单逻辑清楚,覆盖率100%,也就是说二值之后的图片能把所有要找的部分找出来。细心的朋友可能觉得随机撒点不靠谱?确实不靠谱,于是我在撒点算法上改进了一下。
3.我要找的图片部分宽高各50,实际上我只要一个像素点命中我要找的图片部分,通过扩散查找算法,它就能帮我找出来,所以在随机撒点算法里面我改成跳跃式的撒点,只要被找部分在里面就逃不掉。这样撒点和查找结合就能大大提高查找的效率。接下来看图:
可能有些朋友会说,怎么前面有些没查出来?那是因为我跳跃撒点的间距比较大而已。
识别找是找到了,怎么识别呢?有了前面查找提供的基础数据,识别就变的简单了。上图每查找出一个图片轨迹,我就会把它的轨迹像素点存储在一个多维列表里面,通过多张验证码图片比对发现填充的位置部分和填充的图片对象像素点大小不超过50,这样就很容易找到填充位置坐标在哪里。退一步说即便我不用这种方法,我可以根据几何图像相似度也可以处理这个问题,我可以根据边,高,宽,长等特性按比例计算相似度。最后拿到了填充位置计算一下填充图片和填充位置的坐标距离,然后触发js拉动填充图片即可,当然最后一部我就没做了,理论上这么可以做吧。
好了就说这么多吧,本人不是做图像识别的,说的不对或者哪里有错误,希望看官指出,最后谢谢吧。
 
posted @ 2019-11-04 00:21  小菜 。  阅读(1266)  评论(0编辑  收藏  举报