Search code examples
javaarraystraceedge-detection

I'm trying to build a trace method, to trace the coordinates of the outline of a picture in form of a 2dArray


For a school projekt i'm trying to build a trace method. It's supposed to trace the coordinates of the outline of a shape based on an Array from an EdgeDetection method. I made sure the outline is only one pixel thick. Because it's a projekt I can't use any fancy tricks from the libary.

So far i'm using a nested forloop to find the beginning of the shape. Then i'm using a shape like this:

p9  p2  p3
p8  p1  p4
p7  p6  p5

p1 is my present position in the array and then i'm searching p2-p9 for the next position.

The code so far looks like this:

private static String traceCoordinates(int o[][])
{

    String useless = null; 
    //int[][] n = new int[m[0].length][m.length];
    //int[][] o = new int[n.length][n[0].length];

   // n = transpose(m);
    //o = thinning(n);

    int hits = 0;
    System.out.print("        ");
    for (int a = 0; a < 1; a++)
    {
        for (int b = 0; b < o[0].length; b++)
        {
            String c = String.format("%3s", b);
            System.out.print(c + " ");
        }System.out.println("");
    }

    for (int y = 0; y < o.length; y++)
    {
        //String e = String.format("%3s", y).replace(" ", "0");
        //System.out.print("row" + e + " ");
        for (int x = 0 ; x < o[0].length ; x++)
        {
            if (o[y][x] == 0)
            {
                int xEnd = x;
                int yEnd = y;

                int a = y + 1;
                int b = y - 1;
                int c = x + 1;
                int d = x - 1;

                /*
                Her findes værdien af de 8 nabopixler på baggrund af deres indbyrdes index.
                */
                int p2 = o[b][x];
                int p3 = o[b][c];
                int p4 = o[y][c];
                int p5 = o[a][c];
                int p6 = o[a][x];
                int p7 = o[a][d];
                int p8 = o[y][d];
                int p9 = o[b][d];

                do
                {

                    System.out.println(y + ";" + x + " " + "begin");
                    if (p2 == 0 && hits < 1)
                    {
                        System.out.print("This point: ");
                        System.out.print(pntC(x, y) + " ");
                        o[y][x] = 66;
                        y--;
                        System.out.print("Next point: ");
                        System.out.println("2; " + pntC(x, y) + " ");
                        hits++;
                    }
                    else if (p3 == 0 && hits < 1)
                    {
                        System.out.print("This point: ");
                        System.out.print(pntC(x, y) + " ");
                       o[y][x] = 66;
                        y--;
                        x++;
                        System.out.print("Next point: ");
                        System.out.println("3; " + pntC(x, y) + " ");;
                        hits++;
                    }
                    else if (p4 == 0 && hits < 1)
                    {
                        System.out.print("This point: ");
                        System.out.print(pntC(x, y) + " ");
                        o[y][x] = 66;
                        x++;
                        System.out.print("Next point: ");
                        System.out.println("4; " + pntC(x, y) + " ");
                        hits++;
                    }
                    else if (p5 == 0 && hits < 1)
                    {
                        System.out.print("This point: ");
                        System.out.print(pntC(x, y) + " ");
                        o[y][x] = 66;
                        x++;
                        y++;
                        System.out.print("Next point: ");
                        System.out.println("5; " + pntC(x, y) + " ");
                        hits++;
                    }
                    else if (p6 == 0 && hits < 1)
                    {
                        System.out.print("This point: ");
                        System.out.print(pntC(x, y) + " ");
                        o[y][x] = 66;
                        y++;
                        System.out.print("Next point: ");
                        System.out.println("6; " + pntC(x, y) + " ");
                        hits++;
                    }
                    else if (p7 == 0 && hits < 1)
                    {
                        System.out.print("This point: ");
                        System.out.print(pntC(x, y) + " ");
                        o[y][x] = 66;
                        x--;
                        y++;
                        System.out.print("Next point: ");
                        System.out.println("7; " + pntC(x, y) + " ");
                        hits++;
                    }
                    else if (p8 == 0 && hits < 1)
                    {
                        System.out.print("This point: ");
                        System.out.print(pntC(x, y) + " ");
                        o[y][x] = 66;
                        x--;
                        System.out.print("Next point: ");
                        System.out.println("8; " + pntC(x, y) + " ");
                        hits++;
                    }
                    else if (p9 == 0 && hits < 1)
                    {
                        System.out.print("This point: ");
                        System.out.print(pntC(x, y) + " ");
                        o[y][x] = 66;
                        x--;
                        y--;
                        System.out.print("Next point: ");
                        System.out.println("9; " + pntC(x, y) + " ");
                        hits++;
                    }
                    System.out.println(y + ";" + x + " " + "end");
                    hits = 0;

                }while(o[y][x] == 0);   
                System.out.println("loop\n");



            }

        }
        System.out.println("");
    }System.out.println(hits);
    for( int row = 0 ; row < o.length ; row++)
    {//start row for loop
        String e = String.format("%3s", row);
        System.out.print("row" + e + " ");
        for (int column = 0 ; column < o[0].length ; column++)
        {// start column for loop
                           if (o[row][column] == 255)
                            {
                                       System.out.print("___|");
                            }
                           else
                           {
                               System.out.print("   " + o[row][column]);
                           }
        }// end colum for loop

        System.out.println(" end row");
    }// end row for loop
return useless;    
}

When i'm done, the trace is returned through a StringBuilder as a String, hence the useless variable.

My problem is that my method only can detect a line in one direction. When there are no more pixels in that direction, it jumps out of the loop.

I'm practicing on the following array:

int[][] A = new int[][]
    {
        {1,  2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21, 22},
        {2,  0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 2},
        {3,  255, 0,   0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 2},
        {4,  255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 2},
        {5,  255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 2},
        {6,  255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 2},
        {7,  255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 2},
        {8,  255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 2},
        {9,  255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 2},
        {10, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 2},
        {11, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 2},
        {12, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 2},
        {13, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 2},
        {14, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 2},
        {15, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 2},
        {16, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 2},
        {17, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 2},
        {18, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 2},
        {19, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 2},
        {20, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 2},
        {21, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 2},
        {1,  2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21, 22}
    };

What i would lige to see returned is something like this:

1;1 2;2 2;3 3;4 4;4 5;5 6;6 7;7 8;8 9;9 10;10 9;11 8;12 7;13 6;14 5;15 4;16 3;17 2;18 1;19

In that order.

The actual output of the method right now is:

1;1 begin

This point: 001/001 Next point: 5; 002/002
2;2 end 2;2 begin This point: 002/002 Next point: 5; 003/003
3;3 end loop

3;4 begin This point: 004/003 Next point: 6; 004/004
4;4 end 4;4 begin This point: 004/004 Next point: 6; 004/005
5;4 end loop

5;5 begin This point: 005/005 Next point: 5; 006/006
6;6 end 6;6 begin This point: 006/006 Next point: 5; 007/007
7;7 end 7;7 begin This point: 007/007 Next point: 5; 008/008
8;8 end 8;8 begin This point: 008/008 Next point: 5; 009/009
9;9 end 9;9 begin This point: 009/009 Next point: 5; 010/010
10;10 end 10;10 begin This point: 010/010 Next point: 5; 011/011
11;11 end loop

How can i make this work?


Solution

  • For outline following, knowing the current pixel is not enough. You also need the direction from which it was reached. Then you start looking for the next pixel by revolving around the current pixel (clockwise or counterclockwise) starting from the current direction.

    Thus your table should have 8 x 256 entries. Alternatively, you can try the 8 neighbors in turn (in fact 6 suffice). Different space/time tradeoffs are possible.

    To initiate the traversal, you can look for a configuration with a pixel surrounded by a void followed by a pixel. The stopping criterion is a little tricky. For correctness, you should stop when you are back to the initial pixel, ready to continue in the same direction.

    enter image description here