说实话,我在刚接触 OpenCV
的第一天,就想着做一个验证码识别程序。这一篇呢,先讲验证码生成(因为验证码识别还不会做),毕竟生成比识别简单多了嘛!而且昨天刚刚学习了一些 Mat
的知识,生成了许多图像,那么今天就来尝试一下如何生成验证码吧!
思路
我想的生成验证码的思路非常简单,就是一张小图片,然后放一些随机的数字或字母上去,然后再加上一点噪点之类的干扰。那么关键步骤就是如何把文本放上去了。
一般遇到这种问题,我们就会去查阅文档。不过根据我多年的经验,因为我用的是 VS
,我就直接先在 IDE
里敲了一下 text
,果然…在弹出的提示中我就发现了一个 putText
。然后我就敲下括号,就看到了这个函数声明大概长这样:
嗯..看到 renders the specified text string in the image
然后我就确定了没错!这就是我想要的函数!
接着就可以在 官方文档 找到这个函数:
参数确实有点多啊,不过看完它给的参数说明,就都可以理解了:
img
Image.text
Text string to be drawn.org
Bottom-left corner of the text string in the image.fontFace
Font type, see cv::HersheyFonts.fontScale
Font scale factor that is multiplied by the font-specific base size.color
Text color.thickness
Thickness of the lines used to draw a text.lineType
Line type. See the line for details.bottomLeftOrigin
When true, the image data origin is at the bottom-left corner. Otherwise, it is at the top-left corner.
然后我又在中文网上看到了 这个,恰好,想要的东西都齐了。RNG
是 OpenCV
的随机数字生成器,刚好就可以用来完成我们的工作。可以在 这里 查看它的文档。我们主要用到的就是它的 uniform
函数,这个函数可以生成指定范围内分布均匀的随机数。
开始绘图
首先,我们先绘制出一张背景图,我也不确定要多大,先随便给个数。然后构造我们的随机数生成器,我发现如果构造时那个值不变,运行的时候它每次随机的还是一样的,所以就取了当前时间来构造 RNG
。然后随机初始化一张背景,我把数字调大一点,是为了让背景色更亮。
这时候我们就得到一个背景图,当然每次运行都是不一样的:
生成验证码
接着,对照着 putText
的参数,我们写一个函数 generateCode
用于生成验证码。putText
函数里需要用到文本字符串及文本颜色,这两个值也应该是随机的,于是我们先写两个辅助函数 randomText
和 randomColor
:
|
|
我们就先假定生成的验证码中包含了四个数字或字母,用一个循环依次生成:
如果还不明白 putText
中参数的意义,就仔细去阅读文档。而关于 putText
里的参数是怎么来的,其实都是调出来的,一点一点试,调到满意为止 =v= 我们暂时先这样,然后在主函数里加上这个函数:
运行的效果大概是这样:
看起来挺简单吧!
加入干扰
我们看到的验证码,可不仅仅是像我们刚刚生成的那样,往往还会一些“噪点”,比如加入一些乱七八糟的点或线。我们同样也要做这个工作。我们还可以在 这里 找到很多绘制的函数,这可以帮助我们完成这项工作。
说是“噪点”,但实际上一个像素点实在是太小了,所以我使用的是一个很小的圆来代替,对应的函数是 circle
,可以看 这里 的说明。
于是我们写一个 interfere
函数:
把这个函数放在 main
函数的生成验证码后面,然后运行一下,效果大概如下:
这样子看起来不够,我们还可以加入一些随机线条,我使用的是 ellipse
这个函数,它是用于生成椭圆的,我们可以用来生成一些曲线,可以在 这里 查看文档说明。
然后我们在 interfere
里加入这个部分:
再次运行一下,结果大概像这样:
最终效果
到这里我们基本就“完成了”我们丑陋了验证码生成,其实这是非常简陋的。我们还可以自己做更多的尝试,试试其他函数,以及调参。最终,经过再一次的修改,完整代码如下:
以下是生成的验证码的展示图:
还可以吧!有模有样了 ( ̄︶ ̄)↗
去研究验证码识别了 (:з」∠) ,希望下一篇文章能早日出来~