我来顶一下!,楼主的讲述非常精彩,非常简单明了地讲述了怎么识别验证码图片。我曾在上做过如何输出验证码,楼主可是要把我输出的验证码给破解了哈,汗颜~~
借这个帖子,我想在把楼主的思想扩充一下,楼主给出的是在黑白、20像素、特定字体下解读识别验证码的,不过现在的验证码图片做的都很花哨,文字排列也是五花八门,所以在这样一种情况下,恐怕楼主解读验证码的成功率是直线下降罗。
从信息学角度讲,我们是在用一段已经缺失的信息去恢复原来具有冗余的信息,将已经造成模糊和混淆的验证码提取出来,逐步逼近为精确字符。因此我们的终极思路应该是把噪音、模糊和混淆与有用的信息之间的相似度尽可能降低,然后重整字符,形成特征,与现存特征比较从而得出结论。
计算机在处理这类模糊混淆形式时是个难题,因为它不具备人类特有的思维优势。
我看到楼主还有许多文章没有贴出来,如果版主看到的话,我建议不妨将此贴作为讨论贴,让大家来对关于图形图像处理和识别技术的讨论。
我这里有一种思路,
验证码可能是彩色的,且可能加入了很多其他图形用作混淆,但我们假定,混淆图像与字符图象之间从亮度方面仍然存在差异,我们不妨将彩色图像转换为灰度图象来处理,这时色差信息虽然丢失了,但我们能得到仅亮度一个指标的图像。
第二步,对灰度图生成轮廓线,有一个简单的方式,对原图在X和Y轴上移动一个像素,然后与原图每像素相减,在字符与背景、混淆图与背景等相邻像素对比度相差很大的地方就形成了轮廓图。轮廓图也是一个灰度图,但是在前面我们做过假定混淆图案与字符图案存在亮度差,因此他们在输出的轮廓灰度图中也会表现出来。
第三步,用轮廓图执行算法生成包络路径。这个算法就涉及到很多模糊参数了。有了包络路径,我们就可以得到每一个闭合区域的面积,包络线平滑度以及区域内外的亮度差(轮廓线的亮度差),将面积过小的闭合区域舍去(它可能是个干扰图案),多大面积被认定为干扰图案则由参数指定。对于混淆图案与字符图案重叠的地方,我们能够寻找到至少两条边界,通过拟合函数输出与两条边界判定,选取最相近的一条边界。(拟合函数的幂次数决定了拟合曲线平滑程度)。
第四步我们可能需要重新调整包络线的形状。这里,我们又反过来分析字母的包络线。
任何一个字母,均会组成一个闭合区域。对于大写字母来说,诸如QROPADB这一类字母,除了最外轮廓形成闭合区域,内部的包络线还会夹在其中,与外轮廓间形成环形区域,而特别是B字母,它有两个包含在外区域内的内区域,通过比对区域数量,我们立刻可以判定出B这个字母。
现在先考虑我们将各种各样字体、形式的字符,他们的外轮廓中最容易判定的就是折角非常大的几个特征点。例如A字母的顶部和两个脚部,对于大写字母来说,通过仔细分析,我们可以用一个“九宫格”类似的网格,将这些折角点固定在九宫格的不同位置,每个个九宫格的折角分布,一定程度上代表了一个字符。这种“九宫格”姑且就可以作为特征码来使用。
然后再说包络路径图(它已经不是普通意义的位图了,应该是一个连接线和点信息的矢量图),把最容易判定的B字母判定出来,如果不是,接下来对包络路径重整,按照路径上每个点的切线角度将其按照0度45度90度角三条线归类重绘,然后记下他们的折角所处的位置。将其调整到合适的九宫格中,与字母的特征码九宫格比对,即可基本上得到一个字符了。图中存在多个字符,就按照类似的方式重复。
这是我一点点拙劣的思路,至于识别精确率阿什么的,这个也无从考证,关于图像识别的算法,历来就没有什么定论,只有思路,好不好识别率说了算。至于代码,因为思路太复杂,因此我也没有时间去具体实现。
强烈希望斑竹能设为讨论贴,希望各路高手都来讨论一下哈,呵呵