0

I need to recognize objects in binary image.

I have searched on the internet looking for possible algorithms, there are a lot of them, but unfortunately it is very hard to personally for me convert raw formula to the code algorithm without any visual explanation.

I have found this algorithm http://www.izbi.uni-leipzig.de/izbi/publikationen/publi_2004/IMS2004_JankowskiKuska.pdf .

Furthermore there is Java implementation described in this article.

As the author wrote

The method labelImage is now available for use as any Mathematica built-in or user-defined function

Unfortunately not, this algorithm will fail in case of 1 in corners, first,last positions because of missing if checks.

The algorithm is quite easy if we found cell with 1 and it is not labeled already we check neighbors pushing on the stack found items.

But I am not sure that it works correctly. I have modified it, added some if checks in order not to go out of bounds.

Here it is.

 public int[][] labelImage(int stackSize) {
        int nRow = img.length;
        int nCol = img[0].length;
        int marker = 1;
        int[] pos;
        mStack = new SizedStack<>(stackSize);
        int[][] label = new int[nRow][nCol];

        for (int r = 0; r < nRow ; r++)
            for (int c = 0; c < nCol; c++) {

                if (img[r][c] == 0) continue;
                if (label[r][c] > 0) continue;
                /* encountered unlabeled foreground pixel at position r, c */
                /* push the position on the stack and assign label */
                mStack.push(new int[]{r, c});
                label[r][c] = marker;
                /* start the float fill */
                while (!mStack.isEmpty()) {
                    pos = mStack.pop();
                    int i = pos[0];
                    int j = pos[1];
                    // Check if this is not first row, in this case we don't need to check top cells
                    if (i > 0) {
                        if (img[i - 1][j - 1] == 1 && label[i - 1][j - 1] == 0) {
                            mStack.push(new int[]{i - 1, j - 1});
                            label[i - 1][j - 1] = marker;
                        }
                        if (img[i - 1][j] == 1 && label[i - 1][j] == 0) {
                            mStack.push(new int[]{i - 1, j});
                            label[i - 1][j] = marker;
                        }
                        // Check if this is not the last column cell
                        if (j != nCol - 1) {
                            if (img[i - 1][j + 1] == 1 && label[i - 1][j + 1] == 0) {
                                mStack.push(new int[]{i - 1, j + 1});
                                label[i - 1][j + 1] = marker;
                            }
                        }
                    }
                    // Check if this is not first column
                    if (j > 0) {
                        if (img[i][j - 1] == 1 && label[i][j - 1] == 0) {
                            mStack.push(new int[]{i, j + 1});
                            label[i][j + 1] = marker;
                        }
                        // Check if this is not last row
                        if (i != nRow - 1) {
                            if (img[i + 1][j - 1] == 1 && label[i + 1][j - 1] == 0) {
                                mStack.push(new int[]{i + 1, j - 1});
                                label[i + 1][j - 1] = marker;
                            }
                        }
                    }
                    // Check if this is not last row
                    if (i != nRow - 1) {
                        if (img[i + 1][j] == 1 && label[i + 1][j] == 0) {
                            mStack.push(new int[]{i + 1, j});
                            label[i + 1][j] = marker;
                        }
                        // Check if this is not first column
                        if (j != nCol - 1) {
                            if (img[i + 1][j + 1] == 1 && label[i + 1][j + 1] == 0) {
                                mStack.push(new int[]{i + 1, j + 1});
                                label[i + 1][j + 1] = marker;
                            }
                        }
                    }
                }
                marker++;
            }

        return label;
    }
} 

Here is an example and results.

Consider following image

            {1, 0, 0, 0, 0, 1, 0, 1},
            {0, 0, 1, 1, 0, 1, 0, 0},
            {0, 0, 0, 1, 0, 1, 0, 0},
            {0, 1, 0, 1, 0, 0, 0, 1},
            {0, 0, 0, 0, 0, 1, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 1},
            {0, 0, 0, 0, 0, 1, 1, 0},
            {0, 0, 0, 0, 0, 0, 0, 0},

And result

[1, 0, 0, 0, 0, 2, 0, 3]
[0, 0, 4, 4, 0, 2, 0, 0]
[0, 0, 0, 4, 0, 2, 0, 0]
[0, 5, 0, 4, 0, 0, 0, 6]
[0, 0, 0, 0, 0, 7, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 8]
[0, 0, 0, 0, 0, 9, 8, 8]
[0, 0, 0, 0, 0, 0, 0, 0]

The problem here is 6-th and 7-th rows (starting from 1)

As far as I can understand this algorithm uses 8-cohesion,but I thought about it in little bit other way.

  1. Is it correctly recognized 9 as new object ? The algorithm checks neighbors in a such way (U - unchecked, C-checked , X - current cell)

    C C U
    C X U
    C C U

  2. What is wrong with cell [7,8] why it is marked, where is mistake ?

All in all, I have no a lot of experience in image processing and recognition, so I would be grateful for any help or advice of better algorithm and example of using it.

Thanks.

CROSP
  • 4,499
  • 4
  • 38
  • 89
  • apply it to some real images - does it give good results? thats how it works - dont expect someone to go though the code; maybe the authors made some mistakes- you will find them after experimentation - good luck – gpasch Mar 25 '16 at 23:55
  • With the real image the same issue it marks cell which belongs to the object as new object, all this cells are on located on the contour of image – CROSP Mar 26 '16 at 01:34

0 Answers0