自编验证码图片识别程序 自定义的FloodFill函数

最近闲来无事,自编验证码图片识别程序,需要用到FloodFill函数,查了很多资料,都是其他语言的,vb.net语言的资料太少了,我从vb走到vb.net,感觉入门比较容易,其他如c、c++、c#等感觉很难入门。无奈vb.net爱好者太小众,查个资料特别费劲,也想改成其他语言,没有时间啊!!!!!
  每次都唠叨唠叨,自己都烦了,哈哈!

  一、先谈谈泛水填充吧
  还得再唠叨一下,vb.net在画图方面可能比较弱,运行速度慢,但是咱呢,就是识别一个验证码,几百像数的图片,应该也没啥影响。
  1、泛水填充的概念
  泛水填充,也有叫漫水填充,叫啥的都有,甭管叫啥,英文就叫FloodFill, 画图里的油漆桶工具就是用的FloodFill原理。也就是把连通的区域(颜色相同或相近的区域)填充成(换成)某个颜色的过程。简单来说,就是自动选中了和种子点相连的区域,接着将该区域替换成指定的颜色,这是个非常有用的功能,经常用来标记或者分离图像的一部分进行处理或分析.漫水填充也可以用来从输入图像获取掩码区域,掩码会加速处理过程,或者只处理掩码指定的像素点。填充方式一般是4连通和8连通。话不多说,上图(抄别人的图)。

                 第一张图为4连通填充,第二张图为8连通填充
                  
  FloodFill函数很多,多数都是用c和c++写的,其中就包括非常著名的OpenCV,OpenCV适合大计算量的填充计算,非常专业和高效,目前已经有了 2.X版本,有兴趣的可以去其官方网站下载,有幸的是他也有vb.net版本。我也下载备用了,只是安装麻烦。为了个小小的验证码识别,没必要,所以就自己动手做了一个简单的洪水填充函数,不对,好像叫泛水填充,这个乱啊,管他呢。反正功能一样,呵呵!

  2、泛水填充的原理
  泛水填充的原理很多,我才用的是种子填充法,原理如下:
  a、将种子像素赋予一个label,然后将该种子相邻的所有前景像素都压入栈中;
  b、弹出栈顶像素,赋予其相同的label,然后再将与该栈顶像素相邻的所有前景像素都压入栈中;
  c、重复b步骤,直到栈为空;
  此时,便找到了图像中的一个连通区域,该区域内的像素值被标记为label;

二、函数代码
  下面是我的自己定义的floodfill函数代码,与大家分享一下,批评指正,互相提高,不吝赐教!

Private Function mxdFloodFill(ByVal bm As Bitmap, ByVal SeedPoint As Point, ByVal Cr As Color) As Boolean 'seed-fill,4-neighbours,以种子点颜色相同的连通区域进行填充。
' a、将B(x,y)作为种子(像素位置),并赋予其一个label,然后将该种子相邻的所有前景像素都压入栈中;
' b、弹出栈顶像素,赋予其相同的label,然后再将与该栈顶像素相邻的所有前景像素都压入栈中;
' c、重复b步骤,直到栈为空;
' 此时, 便找到了图像B中的一个连通区域, 该区域内的像素值被标记为label;

Dim seedColor As Color = bm.GetPixel(SeedPoint.X, SeedPoint.Y)
Dim StackSeed As New Stack
Dim FourNeighbours As List(Of Point) 

If SeedPoint.X > bm.Width - 1 Or SeedPoint.Y > bm.Height - 1 Then
Return False
Exit Function
End If
StackSeed.Push(SeedPoint)

Do While StackSeed.Count <> 0
Dim PopSeed As Point = StackSeed.Pop
FourNeighbours = GetFourNeighbourSeeds(bm, PopSeed) '上下左右四邻点
For Each point In FourNeighbours
If Not StackSeed.Contains(point) Then
StackSeed.Push(point)
End If
Next
bm.SetPixel(PopSeed.X, PopSeed.Y, newColor)

Loop
Return True
End Function
————————————————

原文地址:https://www.cnblogs.com/hzcya1995/p/13309180.html