图像算法---洪水填充算法函数

洪水填充算法也叫种子生长算法,算法步骤如下:

1,在图像中选择一个种子点,如下图所示:



 

                                                           Fig.1示意图

  种子点为图像中的黑色方框,即黑色像素点。

2,以这个点为起点,将它压入栈中,假设我们要填充的颜色为A,则将该点颜色设置为A,然后判断它的四邻域像素,这里我们设置一个颜色阈值T,假设当前像素灰度值为P(x,y),四邻域像素为M(n),n=1,2,3,4,那么判断当前像素与四邻域像素的灰度差值D=|P-M|,如果D小于T, 那么我们将该像素M作为下一个种子点,压入栈中,否则继续判断。如图中黑色像素的四邻域内有一灰色点,与其差值小于T,则把它作为新的种子点压入栈中,继续判断。

3,当栈为空时,种子填充结束,否则重做步骤2

[函数代码]

        /// 

        /// Flood fill.

        /// 

        /// The source image.

        /// The start point to be filled.

        /// The color to be filled.

        /// One parameter to control fill effect, from 0 to 255.

        /// 

         public static WriteableBitmap FloodfillProcess(WriteableBitmap src,Point location,Color fillColor, int threshold)////洪水填充算法

         {

             if (src != null)

             {

                 int w = src.PixelWidth;

                 int h = src.PixelHeight;

                 Stack<Point> fillPoints = new Stack<Point>(w * h);

                 int[,] mask = new int[w, h];

                 WriteableBitmap fillImage = new WriteableBitmap(w, h);

                 byte[] temp = src.PixelBuffer.ToArray();

                 byte[] tempMask = (byte[])temp.Clone();

                 Color backColor = Color.FromArgb(0,tempMask[(int)location.X * 4 + 2 + (int)location.Y * w * 4], tempMask[(int)location.X * 4 + 1 + (int)location.Y * w * 4], tempMask[(int)location.X * 4 + (int)location.Y * w * 4]);

                 int gray = (int)((backColor.R + backColor.G + backColor.B) / 3);

                 if (location.X < 0 || location.X >= w || location.Y < 0 || location.Y >= h)return null;

                 fillPoints.Push(new Point(location.X, location.Y));

                 while (fillPoints.Count > 0)

                 {

                     Point p = fillPoints.Pop();

                     mask[(int)p.X, (int)p.Y] = 1;

                     tempMask[4 * (int)p.X + (int)p.Y * w*4] = (byte)fillColor.B;

                     tempMask[4 * (int)p.X + 1 + (int)p.Y * w*4] = (byte)fillColor.G;

                     tempMask[4 * (int)p.X + 2 +(int) p.Y * w*4] = (byte)fillColor.R;

                     if (p.X > 0 && (Math.Abs(gray - (int)((tempMask[4 * ((int)p.X - 1) + (int)p.Y * w * 4] + tempMask[4 * ((int)p.X - 1) + 1 + (int)p.Y * w * 4] + tempMask[4 * ((int)p.X - 1) + 2 + (int)p.Y * w * 4]) / 3)) < threshold) && (mask[(int)p.X - 1, (int)p.Y] != 1))

                     {

                         tempMask[4 * ((int)p.X - 1) + (int)p.Y * w*4] = (byte)fillColor.B;

                         tempMask[4 * ((int)p.X - 1) + 1 + (int)p.Y * w*4] = (byte)fillColor.G;

                         tempMask[4 * ((int)p.X - 1) + 2 + (int)p.Y * w*4] = (byte)fillColor.R;

                         fillPoints.Push(new Point(p.X - 1, p.Y));

                         mask[(int)p.X - 1, (int)p.Y] = 1;

                     }

                     if (p.X < w - 1 && (Math.Abs(gray - (int)((tempMask[4 * ((int)p.X + 1) + (int)p.Y * w * 4] + tempMask[4 * ((int)p.X + 1) + 1 + (int)p.Y * w * 4] + tempMask[4 * ((int)p.X + 1) + 2 + (int)p.Y * w * 4]) / 3)) < threshold) && (mask[(int)p.X + 1, (int)p.Y] != 1))

                     {

                         tempMask[4 * ((int)p.X + 1) + (int)p.Y * w * 4] = (byte)fillColor.B;

                         tempMask[4 * ((int)p.X + 1) + 1 + (int)p.Y * w * 4] = (byte)fillColor.G;

                         tempMask[4 * ((int)p.X + 1) + 2 + (int)p.Y * w * 4] = (byte)fillColor.R;

                         fillPoints.Push(new Point(p.X + 1, p.Y));

                         mask[(int)p.X + 1, (int)p.Y] = 1;

                     }

                     if (p.Y > 0 && (Math.Abs(gray - (int)((tempMask[4 * (int)p.X + ((int)p.Y - 1) * w * 4] + tempMask[4 * (int)p.X + 1 + ((int)p.Y - 1) * w * 4] + tempMask[4 * (int)p.X + 2 + ((int)p.Y - 1) * w * 4]) / 3)) < threshold) && (mask[(int)p.X, (int)p.Y - 1] != 1))

                     {

                         tempMask[4 * (int)p.X + ((int)p.Y - 1) * w * 4] = (byte)fillColor.B;

                         tempMask[4 * (int)p.X + 1 + ((int)p.Y - 1) * w * 4] = (byte)fillColor.G;

                         tempMask[4 * (int)p.X + 2 + ((int)p.Y - 1) * w * 4] = (byte)fillColor.R;

                         fillPoints.Push(new Point(p.X, p.Y - 1));

                         mask[(int)p.X, (int)p.Y - 1] = 1;

                     }

                     if (p.Y < h - 1 && (Math.Abs(gray - (int)((tempMask[4 * (int)p.X + ((int)p.Y + 1) * w * 4] + tempMask[4 * (int)p.X + 1 + ((int)p.Y + 1) * w * 4] + tempMask[4 * (int)p.X + 2 + ((int)p.Y + 1) * w * 4]) / 3)) < threshold) && (mask[(int)p.X, (int)p.Y + 1] != 1))

                     {

                         tempMask[4 * (int)p.X + ((int)p.Y + 1) * w * 4] = (byte)fillColor.B;

                         tempMask[4 * (int)p.X + 1 + ((int)p.Y + 1) * w * 4] = (byte)fillColor.G;

                         tempMask[4 * (int)p.X + 2 + ((int)p.Y + 1) * w * 4] = (byte)fillColor.R;

                         fillPoints.Push(new Point(p.X, p.Y + 1));

                         mask[(int)p.X, (int)p.Y + 1] = 1;

                     }

                 }

                 fillPoints.Clear();

                 temp = (byte[])tempMask.Clone();

                 Stream sTemp = fillImage.PixelBuffer.AsStream();

                 sTemp.Seek(0, SeekOrigin.Begin);

                 sTemp.Write(temp, 0, w * 4 * h);

                 return fillImage;

             }

             else

             {

                 return null;

             }

         }

[图像效果]

           Fig.2 原图                                 Fig.3效果图


demo下载: http://www.zealfilter.com/forum.php?mod=viewthread&tid=121&extra=page%3D1

你可能感兴趣的:(图像基本变换)