2015年8月19日
验证码粘连字符分割经验谈
验证码粘连字符分割作为业余学习课题已经有一段时间了,分割对象是TAOBAO上白底蓝字的四字符粘连的验证码。期间主要研究了两类分割算法。第一类是寻找细化字符的谷点,然后根据谷点对粘连字符进行分割;第二类是基于字符特征来对粘连字符进行分割,也就是本博客中连载的《粘连字符“花式分割”》。
根据两种分割算法的实验效果,第二类的分割效果要优于第一类,本文主要介绍第二类算法实现过程中的一些经验。第二类算法即《粘连字符“花式分割”》,其参考文献是<The Robustness of “Connecting Characters Together” CAPTCHAs>。目前只能算是一个大体的框架,并未将原参考文献的精髓体现出来,源代码可以到https://github.com/livezingy/merged-characters-segmentation进行下载。当前阶段《粘连字符“花式分割”》对13个样本的分割效果如下。
基于字符特征的分割算法主要是依据loop principle和guideline principle找到分割点,以此分割点为起点执行滴水算法进行分割。该算法的优点是:对于含自然loop的粘连字符(例如B/D/O/P/R/b/d/g/O/p/q/6/8/9)等等,可以实现较完美的分割,而不足之处和需要改善的地方则有许多。
1.对于严重倾斜的自然loop,难以找到一个比较完美的分割点,例如“K2Qm”便是因为Q字母倾斜严重导致分割失败。严格来讲,按照程序中的原则找到的分割点是基本准确的,但是以该点为起始点执行滴水算法来进行分割会导致字符畸形,如果其右侧粘连点采用斜线分割效果会较好。那么现在问题就来了,我们以何标准来决定采用斜线分割呢?
2.对于非自然loop若按照自然loop的原则进行分割,易导致分割错误,例如“CThA”。这样就涉及到找到loop后,需要区分哪些为自然loop,哪些为非自然loop,同时还需要为不同类型的非自然loop制定不同的分割方案,这一点比较复杂。
3.对于某些共用笔画的粘连字符无法正确分割,例如“nRnD”,其中nD共用一条竖线,导致程序较难判断合适的分割点。
4.从近期的学习经验来看,如果粘连字符的笔画宽度为单像素,那滴水算法来分割这些粘连区域几乎是万能的,当然如果字符宽度为单像素,很多问题都迎刃而解。但这是不可能的,所以滴水算法得到的路径并非万能,例如”3c7x”,”pZy6″,分割点起始点是对的,但是因为滴落时,笔画宽度较宽,导致分割结果畸形。这种问题点该如何对策呢?我能想到两种方式:一种是根据已滴落的路径的特征决定后续路径是否要变更为斜线分割;另一种方法是有一种完美的细化算法,细化后的字符可以粘连,但是不允许有畸形。不过这两种想法实现起来似乎都不是太容易。
5.在上述分割失败的验证码图片中还有”UmWy””JX4V”,这类字符的分割不能仅仅依靠字符在四线三格中的位置,还需要更细化其字符特征,根据特征量身定制分割方案。
6.仅仅依靠loop和guideline,对于一些特殊字符可能无法完成分割,例如字符W,s,G,r。不过,目前算法离原参考文献的精髓还有很大的差距,而且在原参考文献中,还有很多其他的算法,例如Cut head and tail(CHT),Even cut, Extraction等等。若能按照原参考文献来实现,分割这些字符应该不存在困难。
近期突然对研究验证码粘连字符分割这件事产生了审美疲劳,因此准备暂停对它的学习,后续是否继续依情况而定。
阿婆主加油,等后续。
好东西 谢谢分享
代码有死循环,用别的验证码
谢谢指出,能麻烦你告诉我死循环的位置吗?非常感谢!
FillConnectedArea这个函数会死循环,是用其它的验证码
请问是否有处理该死循环的建议呢?还请不吝赐教,非常感谢!
Excellent work! The results are impressive!
Is there any way to modify the code to accept a parameter that defines the number of expected characters?
I’ve tried to find these entry points and change them, however I still only get 4 cuts.
博主你好,请问您试过用MATLAB来写这类代码吗?
不好意思,没有用MATLAB写过类似的代码