Search code examples
c#arrayspixel

How do I iterate over a pixel array from a specific location to find a vertical/horizontal line of pixels?


enter image description here

Hello I am trying to create a line from a list of points I will find by traversing an array of pixels. It's basically a box in an image but I know the center point of the box. So I want to loop through the image diagonally and see if the pixels change from 0 to 1 so I know that's part of the box. I want to find the right vertical side of the box first but then change the algorithm to also find it's bottom.

I know how to normally traverse an image but can't figure out how to modify it for my purpose:

        var horizontalLinePoints = new List<Point>();
        var verticalLinePoints = new List<Point>();
        for (int x = centralPoint.X; x < originalImageWidth; x++)
        {
            for (int y = centralPoint.Y; y < originalImageHeight; y++)
            {
                int index = originalImageWidth * x + y;
                if (newImagePixelArray[index] == 1)
                {
                   horizontalLinePoints.Add(new Point(x, y)); 
                }
            }
        }

newImagePixelArray is a one-dimensional byte array.

EDIT:

To further explain I want to determine the angle of the box to see if it's tilted. Some of the suggestions list finding the first pixel to the right then traversing that pixel vertically to determine the each point along that line. I believe the code to at least move right finding the first pixel is this:

// List to store locations of vertical lines pixels
        var verticalLinePoints = new List<Point>();
        // Loop horizontally
        for (int x = centralPoint.X; x < originalImageWidth; x++)
        {
            int index = originalImageWidth * x + centralPoint.Y;

            // Find the first 'vertical' pixel
            if (newImagePixelArray[index] == 1)
            {
                verticalLinePoints.Add(new Point(x, centralPoint.Y));
                break;
            }
        }

EDIT 2:

@TaW has an appropriate algorithm to accomplish this, I was however able to create the logic to find my line:

var verticalLinePoints = new List<Point>();
        var horizontalLinePoints = new List<Point>();
       for (int x = 0; x < originalImageWidth; x++)
       {
           for (int y = centralPoint.Y; y < originalImageHeight; y++)
           {
               int index = originalImageWidth * x + y;
               if (newImagePixelArray[index] >= 1)
               {
                   verticalLinePoints.Add(new Point(x, y));
               }
           }
       }   

Solution

  • Your edited question now makes sense. Still the best way is to go straight, say, to the right until you hit a point on the right border, let's call it R.

    Then repeat straight up and down from the center point until you have one point on the upper and lower border, say T and B.

    Next you follow the y-coordinate of point R both up and down, until they leave the border. The points where they do shall be called R0 and R3; the last points before they do shall be called R1 and R2.

    If R1 and R2 have the same y-coodinates as T and B your box is not tilted. To get the angle you can measure it from the line through R0 and R3.

    To get the most precise angle you would have to repeat the procedure for a horizontal line and then use the longer distance.