Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Simple Algorithm Not working

  1. Feb 21, 2015 #1
    Hey all, I'm currently working on an app that requires the a sub routine to extract 'blob"s from images, ie if I have multiple black shapes on a white background split them into seperate images. Google turned up nothing, my soultion was to
    1. flood fill pixel(0,0) with color[0]
    2.add color to used color list
    3. iterate over all pixels, if currently pixels's color isn't in the used array then flood fill that and add that colro to the used array.

    Then after this id seperate the images by color, make sense? Problem, steps 1-3 arn't working.

    Code (Text):
      List<Color> used=new List<Color>();
             
                Bitmap b1= (Bitmap)pictureBox1.Image;
                int u = 0;      
                LexicalAnalyzer.FloodFill((Bitmap)b1, 0, 0, Binarize.colors[0]);
                used.Add(Binarize.colors[0]);
           
                    for (int i = 0; i < b1.Width; i++)
                    {
                   
                        for (int j = 0; j < b1.Height; j++)
                        {                    
                            if (!In(used.ToArray(), b1.GetPixel(i, j)))
                            {
                                u++;                        
                                LexicalAnalyzer.FloodFill((Bitmap)b1, 0, 0, Binarize.colors[u]);
                                Thread.Sleep(100);
                                used.Add(Binarize.colors[u]);
                            }
                        }
                    }
           
                pictureBox1.Image = b1;
            }

    bool In(Color[] y, Color c)
            {
                for (int i = 0; i < y.Length; i++)
                {
                    if (c.R != y[i].R) return false;
                    if (c.G != y[i].G) return false;
                    if (c.B != y[i].B) return false;
                }
                return true;
            }
    Anyone see any issues? When the code runs after i=8 j=63 it's used 23 colors, and there are only 17 shapes in the image, if i pause the code there the background is purple (color 23) and the other shapes are still black. Any help apreciated.
     
  2. jcsd
  3. Feb 21, 2015 #2
    Code (Text):
      public static void FloodFill(Bitmap bitmap, int x, int y, Color color)
            {
                BitmapData data = bitmap.LockBits(
                    new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                    ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                int[] bits = new int[data.Stride / 4 * data.Height];
                Marshal.Copy(data.Scan0, bits, 0, bits.Length);

                LinkedList<Point> check = new LinkedList<Point>();
                int floodTo = color.ToArgb();
                int floodFrom = bits[x + y * data.Stride / 4];
                bits[x + y * data.Stride / 4] = floodTo;

                if (floodFrom != floodTo)
                {
                    check.AddLast(new Point(x, y));
                    while (check.Count > 0)
                    {
                        Point cur = check.First.Value;
                        check.RemoveFirst();

                        foreach (Point off in new Point[] {
                    new Point(0, -1), new Point(0, 1),
                    new Point(-1, 0), new Point(1, 0)})
                        {
                            Point next = new Point(cur.X + off.X, cur.Y + off.Y);
                            if (next.X >= 0 && next.Y >= 0 &&
                                next.X < data.Width &&
                                next.Y < data.Height)
                            {
                                if (bits[next.X + next.Y * data.Stride / 4] == floodFrom)
                                {
                                    check.AddLast(next);
                                    bits[next.X + next.Y * data.Stride / 4] = floodTo;
                                }
                            }
                        }
                    }
                }

                Marshal.Copy(bits, 0, data.Scan0, bits.Length);
                bitmap.UnlockBits(data);
            }
    That's the flood fill,
     
  4. Feb 21, 2015 #3
    "LexicalAnalyzer.FloodFill((Bitmap)b1, 0, 0, Binarize.colors);"
    Found my problem, should be "i,j" not "0,0". Apologies.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook