-3

Assume we have following binary image

0010
0101
0101
0010
0100
1010
0100
0000

0 represents background pixels and 1 represents image pixels.As you can see there are two holes in this image.Is there a way to obtain the number of holes in this image using algorithms?(Java or Python but not Matlab)

Hussey123
  • 479
  • 1
  • 5
  • 21
  • 4
    This doesn't make any sense to me. Where are those holes? – Fusseldieb Oct 19 '16 at 10:39
  • Would you clearly explain what are holes? – Kian Oct 19 '16 at 10:41
  • your definition of a Hole is incomplete. what is the exact definition of a hole? – Timothy Truckle Oct 19 '16 at 10:41
  • 1
    I believe a hole is an area of `0`s which is surrounded by `1`s. – SubOptimal Oct 19 '16 at 10:42
  • 4
    Of course there is a way. But this looks like homework in basic image processing. In which case, your question should include your own attempt to solve the question, and what problems you encountered in that solution. – RealSkeptic Oct 19 '16 at 10:43
  • It still should no matter if it’s homework or not. Please. – Ole V.V. Oct 19 '16 at 11:02
  • @Ssein Hole is a area surround by 1.In (2 nd row 3 rd column) and (3rd row 3rd column) we have two zeros which belong to same hole.And in 6th row 2nd column we have another hole with one zero.Total we have two holes. – Hussey123 Oct 19 '16 at 11:02
  • I tried `Finding holes in a binary image -matlab` in my search engine, it seems to turn up interesting stuff. Try the same. – Ole V.V. Oct 19 '16 at 11:05
  • @RealSkeptic This isn't any homework.Just need an algorithm to get an idea.I am not requesting any code. – Hussey123 Oct 19 '16 at 11:07
  • @OleV.V. Matlab has an inbuilt function to do this.What I need is the logic behind that functionn – Hussey123 Oct 19 '16 at 11:08
  • 1
    @TimothyTruckle Hole is a area surround by 1.In (2 nd row 3 rd column) and (3rd row 3rd column) we have two zeros which belong to same hole.And in 6th row 2nd column we have another hole with one zero.Total we have two holes. – Hussey123 Oct 19 '16 at 11:09
  • Are you after the exact logic Matlab uses, or just a reasonable algorithm to obtain the same result? – Ole V.V. Oct 19 '16 at 11:12

3 Answers3

3

I have a program on С# that calculates the Euler's number

We can calculate Euler's number according to this formula: Eu = (Q3 - Q1)/4;

Q1 - 00 or 00 or 01 or 10
     01    10    00    00

Q3 - 01 or 11 or 10 or 11 11 10 11 10.

So we go through the matrix, choosing 4 pixels at every step. The algorithm that I wrote counts the Euler's number by this formula. Sorry for my English. This is my github repository with full project: https://github.com/zeComedian/image-processing
public void BWEuler(int[,] image)
{
    int Q1 = 0;
    int Q3 = 0;

    int rows = image.GetUpperBound(0) + 1;
    int columns = image.Length / rows;
    for (int i = 1; i < columns - 1; i++)
    {
        for (int j = 1; j < rows - 1; j++)
        {
            if (image[i, j] == 0)
            {
                if ((image[i, j - 1] != 0) && (image[i - 1, j] != 0))
                {
                    Q3++;
                }
                if ((image[i - 1, j] != 0) && (image[i, j + 1] != 0))
                {
                    Q3++;
                }
                if ((image[i, j + 1] != 0) && (image[i + 1, j] != 0))
                {
                    Q3++;
                }
                if ((image[i + 1, j] != 0) && (image[i, j - 1] != 0))
                {
                    Q3++;
                }
            }
            else
            {
                if ((image[i, j - 1] != 1) && (image[i - 1, j] !=
        1))
                {
                    Q1++;
                }
                if ((image[i - 1, j] != 1) && (image[i, j + 1] !=
      1))
                {
                    Q1++;
                }
                if ((image[i, j + 1] != 1) && (image[i + 1, j] !=
       1))
                {
                    Q1++;
                }
                if ((image[i + 1, j] != 1) && (image[i, j - 1] !=
       1))
                {
                    Q1++;
                }
            }
        }
    }
    int Eu = ((Q3 - Q1) / 4);
    textBox3.Text = Eu.ToString();
    Console.WriteLine(Eu);

}
j_dev
  • 31
  • 8
  • 3
    Please provide more information, Like how this code works and how it fixes the problem? – DarkSuniuM Oct 17 '18 at 11:21
  • We can calculate Euler's number according to this formula: Eu = (Q3 - Q1)/4; Q1 - 0001 or 0010 or 0100 or 1000 Q3 - 0111 or 1110 or 1011 or 1110 The algorithm that I wrote counts the Euler's number by this formula – j_dev Nov 20 '18 at 18:15
  • Better to add it to the post, not everyone going to read the comments, Thanks – DarkSuniuM Nov 20 '18 at 19:30
2

Here is some idea presented as code (and it might be not what you need).

The problem is, that i don't understand your example. Depending on the neighborhood-definition, there are different results possible.

  • If you have a 8-neighborhood, all zeros are connected somehow (what does that mean about the surrounding 1's?).
  • If you have a 4-neighborhood, each one surrounded by 4 1's represents a new hole
    • Of course you could postprocess this but the question is still unclear

Code

import numpy as np
from skimage.measure import label

img = np.array([[0,0,1,0],
                [0,1,0,1],
                [0,1,0,1],
                [0,0,1,0],
                [0,1,0,0],
                [1,0,1,0],
                [0,1,0,0],
                [0,0,0,0]])

labels = label(img, connectivity=1, background=-1)  # conn=1 -> 4 neighbors
label_vals = np.unique(labels)                      # conn=2 -> 8 neighbors

counter = 0
for i in label_vals:
    indices = np.where(labels == i)
    if indices:
        if img[indices][0] == 0:
            print('hole: ', indices)
            counter += 1


print(img)
print(labels)
print(counter)

Output

('hole: ', (array([0, 0, 1, 2, 3, 3, 4]), array([0, 1, 0, 0, 0, 1, 0])))
('hole: ', (array([0]), array([3])))
('hole: ', (array([1, 2]), array([2, 2])))
('hole: ', (array([3, 4, 4, 5, 6, 6, 6, 7, 7, 7, 7]), array([3, 2, 3, 3, 0, 2, 3, 0, 1, 2, 3])))
('hole: ', (array([5]), array([1])))
[[0 0 1 0]
 [0 1 0 1]
 [0 1 0 1]
 [0 0 1 0]
 [0 1 0 0]
 [1 0 1 0]
 [0 1 0 0]
 [0 0 0 0]]
[[ 1  1  2  3]
 [ 1  4  5  6]
 [ 1  4  5  6]
 [ 1  1  7  8]
 [ 1  9  8  8]
 [10 11 12  8]
 [ 8 13  8  8]
 [ 8  8  8  8]]
5
sascha
  • 32,238
  • 6
  • 68
  • 110
0

Try using OpenCV connectedComponents function.

a=np.full((3,3), 1)
a[1,1]=0
print(a) >> [[1,1,1],[1,0,1],[1,1,1]]
n,comp=cv2.connectedComponents(1-a) # 1-a, because components are considered white (non zero)
print(n-1) # number of holes
google2
  • 315
  • 3
  • 8