赞
踩
写在最前面:
本文只会讲思路,不会放代码,不会放代码,不会放代码,重要的事情说三遍。
因为这个事情还是比较敏感的,顶象在验证码方向做的也算是比较大的了,国内很多公司在用的验证码都是顶象的,代码就不放了,避免被人拿去做坏事了。
另外,也是为顶象的验证码做个简单的测试。如果有顶象的大佬看到,可以考虑把这个验证码更新一下啦~
纯一时手痒,仅为技术交流,请勿用于任何商业活动,也请勿对顶象的验证码进行攻击,感谢~
请不要进行任何违法行为,否则后果自负!
以下正文。
前两天有位大佬丢过来一张验证码图片,问我该如何处理。验证码它长这样,要求是点击图片中被分割出来的最大的区域:
哟吼,这验证码,有点东西啊~
但是大佬问的问题,说什么也得给搞定嘛~
于是,我思索了一下,一个想法慢慢成形,我觉得可以把任务拆解成几个小问题:
略微推敲了几遍,觉得想法可行,于是,开搞~
转载请注明来源:https://blog.csdn.net/aaronjny/article/details/110245896
先来解决第一个问题,怎么检测出图片中被标记出来的点。
我最直接的想法是使用目标检测算法,因为这些点还是挺明显的,目标检测模型(比如yolo)应该是可以奏效的。但是一张图片上的点比较多,标注数据集感觉很麻烦,虽然觉得可行,但真心不想费那么大功夫。
又看到标记点的颜色和正常图片的颜色还是有一定差别的,于是,我决定先尝试直接在图片的像素和色值上下些功夫。
考虑到标记点和正常图片的颜色上的差别,可以初步判断一个标记点和周围的其他像素点在色值上是有一定偏离的,我们可以考虑把色值与相邻局部区域整体色值有一定大小偏离的点,认为是标记点。
emmm,话比较绕是吧?感觉不太好理解?那我来举个例子:
有一只哈士奇混在了一群狼里面,虽然都是犬科,但是长得还是不太一样的,我们需要把二哈揪出来~
我们以前面的示例图片为例,解释一下这个问题,请看:
以蓝色框圈起来的绿色点群(实际上是很多绿色点聚在一起了,不只是一个点)为例,在蓝色框选中的图片区域里可以看到,虽然已经有不少绿色点了,但这个点的数量占蓝色框里的全部点的比例还是偏少的,更多的是正常的点。
假如说把蓝色框扩大,变成红色框,会发现,虽然绿色点数量增加了,但正常点的数量增加的更多,绿色点的比例进一步降低了。
那么,相对于正常点来说,标记点的色值就是离群值了(偏离了周围正常点的色值范围)。那么,我们就可以先设定一个框框,然后滑动这个窗口,遍历整张图片,计算窗口在每个位置检测出离群值的点,这些点就可以作为标记点。
那么,具体该怎么做呢?
其实检测离群点的算法有很多,我这里介绍一种,绝对中位差法。
①对于一个h*w的矩阵M,先统计其中位数,即为median
。
②对于矩阵M中的每一个值,都是用它减去 median
,并取绝对值,获得新的矩阵N。
③对N求中位数,即中位差,我们记为mad
。
④我们认为在区间 [median-x*mad,median+x*mad]
内的点属于正常点,超出则为离群点,x看情况设置,我们这里取3。
如果使用 numpy
来描述这个过程的话,如果要检测点(row,col)是否为离群值,可以表示如下:
median = np.median(M)
mad = np.median(np.abs(M - median))
lower_limit = median - 3 * mad
upper_limit = median + 3 * mad
if lower_limit <= im[row][col] <= upper_limit:
print('正常值')
else:
print('离群值')
有几点要注意的是:
如果还不明白的话,我再举个具体的例子,我随便编了一个小矩阵,5*9的,如下图蓝色框所示:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。