在二进制图像中查找孔

时间:2016-10-19 10:37:15

标签: java python algorithm binary-image

假设我们有以下二进制图像

0010
0101
0101
0010
0100
1010
0100
0000

0表示背景像素,1表示图像像素。您可以看到此图像中有两个孔。有没有办法使用算法获取此图像中的孔数?(Java或Python但不是Matlab)< / p>

3 个答案:

答案 0 :(得分:2)

以下是一些以代码形式呈现的想法(可能不是您需要的)。

问题是,我不明白你的例子。根据邻域定义,可能会有不同的结果。

  • 如果你有一个8邻域,所有零都以某种方式连接(这对于周围的1是什么意思?)。
  • 如果你有一个4邻域,每个被4 1包围的代表一个新洞
    • 当然你可以对此进行后处理,但问题仍然不清楚

代码

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)

输出

('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

答案 1 :(得分:1)

我在С#上有一个程序,可以计算欧拉数

我们可以根据以下公式计算欧拉数: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.

    因此,我们遍历矩阵,每步选择4个像素。 我编写的算法通过此公式计算欧拉数。 对不起我的英语不好。 这是我的GitHub存储库,其中包含完整的项目: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);

}

答案 2 :(得分:0)

尝试使用OpenCV connectedComponents函数。

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