Find an area based on a set of points

Given a list of x, y coordinates and a known width and height, how do I determine the NUMBER of surrounded areas (in C #)?

Example:

enter image description here

5 ENCLOSED AREAS are defined in this image :

  • Face (1)
  • Eyes (2)
  • Nose (1)
  • Person's Right (1)

The list of x, y points will be any pixel in black, including the mouth.

+5
source share
4 answers

You can use this simple algorithm based on the idea of ​​filling the fill with a helper bitmap:

// backColor is an INT representation of color at fillPoint in the beginning.
// result in pixels of enclosed shape.
private int GetFillSize(Bitmap b, Point fillPoint)
{
   int count = 0;
   Point p;
   Stack pixels = new Stack();
   var backColor = b.GetPixel(fillPoint.X, fillPoint.Y);
   pixels.Push(fillPoint);
   while (pixels.Count != 0)
   {
       count++;

       p = (Point)pixels.Pop();
       b.SetPixel(p.X, p.Y, backColor);

       if (b.GetPixel(p.X - 1, p.Y).ToArgb() == backColor)
           pixels.Push(new Point(p.X - 1, p.Y));

       if (b.GetPixel(p.X, p.Y - 1).ToArgb() == backColor)
           pixels.Push(new Point(p.X, p.Y - 1));

       if (b.GetPixel(p.X + 1, p.Y).ToArgb() == backColor)
           pixels.Push(new Point(p.X + 1, p.Y));

       if (b.GetPixel(p.X, p.Y + 1).ToArgb() == backColor)
           pixels.Push(new Point(p.X, p.Y + 1));
   }

   return count;
}

UPDATE

In the above code, only these closed areas with four connections work. The following code works with closed closed areas.

// offset points initialization.
Point[] Offsets = new Point[]
{
    new Point(-1, -1),
    new Point(-0, -1),
    new Point(+1, -1),
    new Point(+1, -0),
    new Point(+1, +1),
    new Point(+0, +1),
    new Point(-1, +1),
    new Point(-1, +0),
};

...

private int Fill(Bitmap b, Point fillPoint)
{
    int count = 0;
    Point p;
    Stack<Point> pixels = new Stack<Point>();
    var backColor = b.GetPixel(fillPoint.X, fillPoint.Y).ToArgb();
    pixels.Push(fillPoint);
    while (pixels.Count != 0)
    {
        count++;

        p = (Point)pixels.Pop();
        b.SetPixel(p.X, p.Y, Color.FromArgb(backColor));

        foreach (var offset in Offsets)
            if (b.GetPixel(p.X + offset.X, p.Y + offset.Y).ToArgb() == backColor)
                pixels.Push(new Point(p.X + offset.X, p.Y + offset.Y));
    }

    return count;
}

, . , .

Connectedness

+2

OpenCV. .net, Emgu CV

, Emgu CV: .Net(dotNet) OpenCV?

. cvContourArea, .

, , , . .

+2

. , .

, . (. Servy).

. , . , .

+1

, () . , , HashSet<>, , , , , .

, ( ///), . , .

Your area region count / (pixelWidthOfTotalDrawing * pixelHeightOfTotalDrawing)multiplied by the region of the full rectangle (depending on the units you want).

Comment: I don’t think it looks like a polygon. That is why I had the opportunity to “paint” simple paint software.

+1
source

All Articles