Question

I'm trying to calculate the edges of a black object within a .png file. And by that I mean find the column and row values that makeup a box that encapsulates an object. I attached a link to the photo I created which draws the box according to the values I find. As you can see the top, bottom, and right lines seem to line up correctly, but if you zoom in to the left line, part of the image is outside of the box. Why is that? I have an algorithm which I'll post below that searches every pixel in the array and finds the last occurrence of pixel values != 0 for the top, bottom, left and right sides. For some reason that extra image on the left side is registering pixels that are == 0... Are the values being rounded down to zero? If somebody could explain what is happening that would be great.

Here is a link to the image: http://i.imgur.com/UG8Cghe.png. You really have to zoom into the left side to see what I am talking about. Downloading the image and viewing is probably a necessity. It is a VERY small detail.

Here is the method that converts the BufferedImage(.png) to a 2D Array:

private static int[][] loadImageTo2D(String file_path)
{
    img = null;
    try { img = ImageIO.read(new File(file_path)); } 
    catch (IOException e) { System.out.println(e); }

    int width = img.getWidth();
    int height = img.getHeight();
    int[][] pix = new int[height][width];

    for (int row = 0; row < height; row++) 
    {
         for (int col = 0; col < width; col++) 
         {
            pix[row][col] = img.getRGB(col, row);
         }//for
    }//for

    return pix;
}//loadImageTo2D

Here is how I am searching for the sides:

private static int[] getPerim(int[][] pix)
{
    //Array holds object boundary edges.
    int[] lines = new int[4];
    lines[BOTTOM] = 0;
    lines[TOP] = pix.length;
    lines[LEFT] = pix[0].length;
    lines[RIGHT] = 0;

    //Top down iteration, find the first and last row and column of the 
    //actual graphic.
    for (int row = 0; row < pix.length; row++)
    {   
        for(int col = 0; col < pix[0].length; col++)
        {
            if (pix[row][col] != 0)
            {
                if (row < lines[TOP]) { lines[TOP] = row; }
                else if (row > lines[BOTTOM]) { lines[BOTTOM] = row; }
                else if (col < lines[LEFT]) { lines[LEFT] = col; }
                else if (col > lines[RIGHT]) { lines[RIGHT] = col; }
            }//if
        }//for
    }//for

    return lines;
}//getPerim

I'm then using lines[] to draw the blue box you see in image. Help!

Was it helpful?

Solution

Drop the else part of if else and make all of them ifs . Only one of those if elses can be executed. What happens if pixel is the most down and most left pixel? It will be only used as the most bottom one, as the if-else statement won't get to the col part. I suggest you change it to

            if (row < lines[TOP]) { lines[TOP] = row; }
            if (row > lines[BOTTOM]) { lines[BOTTOM] = row; }
            if (col < lines[LEFT]) { lines[LEFT] = col; }
            if (col > lines[RIGHT]) { lines[RIGHT] = col; }

And no, you can't group left border with right border, as they can be on the same pixel.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top