-3

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

0010
0101
0101
0010
0100
1010
0100
0000

0 代表背景像素,1 代表图像像素。如您所见,此图像中有两个孔。有没有办法使用算法获得此图像中孔的数量?(Java 或 Python,但不是 Matlab)

4

3 回答 3

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
于 2016-10-19T11:36:36.600 回答
1

我在 С# 上有一个计算欧拉数的程序

我们可以根据这个公式计算欧拉数:Eu = (Q3 - Q1)/4;

Q1 - 00 或 00 或 01 或 10
     01 10 00 00

Q3 - 01 或 11 或 10 或 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);

}
于 2018-10-17T11:18:46.310 回答
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
于 2017-08-07T21:04:43.737 回答