views:

38

answers:

1

I'm using GetPixel to get the colour of each pixel of an image. The images contain different plain-coloured irregular shapes, and I'd like to find the point (or pixel) where the maximum width matches the maximum height (see figure below).

alt text

(disregard the border)

I'm using this to iterate through the captured bitmap:

        for (int x = 0; x < bmp.Width; x++)
        {
            for (int y = 0; y < bmp.Height; y++)
            {
                Color clr = bmp.GetPixel(x, y);

                // Hit
                if (TestColour(clr)) // See if we're within the shape. I'm just comparing a bunch of colours here.
                {
                    // Stuff I don't know
                }
            }
        }

I got it to work by using a hashTable, but I understand that it's an dawful solution. I was thinking in the lines of just having two integers (one for X, one for Y) increment and save the maximum value for each iteration, then compare this to the previous one and replace the value if it's higher.

I don't see how I'd be able to use that approach with my for-loops nested like that.

Any input?

+1  A: 

It should be simple to find this point using two loops, similar to the loop you have. First, define your variables:

//from http://www.artofproblemsolving.com/Wiki/images/a/a3/Convex_polygon.png
Image image = Image.FromFile(@"C:\Users\Jacob\Desktop\Convex_polygon.png");
Bitmap bitmap = new Bitmap(image);
Point maxPoint = new Point(0, 0);
Size maxSize = new Size(0, 0);

Next, I would recommend calling GetPixel only once per pixel, and cache the results in an array (this may be a bias from when I had to use an API call to get the pixel, but will prove easier to work with):

Color[,] colors = new Color[bitmap.Width, bitmap.Height];
for (int x = 0; x < bitmap.Width; x++)
{
    for (int y = 0; y < bitmap.Height; y++)
    {
        colors[x, y] = bitmap.GetPixel(x, y);
    }
}

Next, here's a simple code to get the maximum height, and the X of the first point with that height:

Color shapeColor = Color.FromArgb(245, 234, 229);

for (int x = 0; x < bitmap.Width; x++)
{
    int lineHeight = 0;
    for (int y = 0; y < bitmap.Height; y++)
    {
        if (colors[x, y] == shapeColor) // or TestColour(colors[x, y])
            lineHeight++;
    }
    if (lineHeight > maxSize.Height)
    {
        maxSize.Height = lineHeight;
        maxPoint.X = x;
    }
}

You can make a similar loop for each y to find the maximal width.

An important point here: your question isn't defined for concave shapes - on concave shapes you will have a list of heights for every x, and the maximal height line may not intersect the maximal width. Even on convex shapes you may have more than a single answer: a simple example of it is a rectangle.

Kobi