2017-09-04 33 views
2

我有一个2D布尔numpy的阵列来表示影像,在我称之为skimage.measure.label标记每个分割的区域,让我INT [0500]的2D阵列;此数组中的每个值代表该像素的区域标签。我想现在删除最小的区域。例如,如果我的输入数组是形状(n,n),我希望将所有标记为< m像素的区域归入较大的周围区域。例如,如果N = 10和M = 5,我的输入可以是,的Python numpy的阵列 - 接近最小的区域

0, 0, 0, 0, 0, 0, 0, 1, 1, 1 
0, 0, 0, 0, 0, 0, 0, 1, 1, 1 
0, 0, 7, 8, 0, 0, 0, 1, 1, 1 
0, 0, 0, 0, 0, 0, 0, 1, 1, 1 
0, 0, 0, 0, 0, 2, 2, 2, 1, 1 
4, 4, 4, 4, 2, 2, 2, 2, 1, 1 
4, 6, 6, 4, 2, 2, 2, 3, 3, 3 
4, 6, 6, 4, 5, 5, 5, 3, 3, 5 
4, 4, 4, 4, 5, 5, 5, 5, 5, 5 
4, 4, 4, 4, 5, 5, 5, 5, 5, 5 

,输出为然后,

0, 0, 0, 0, 0, 0, 0, 1, 1, 1 
0, 0, 0, 0, 0, 0, 0, 1, 1, 1 
0, 0, 0, 0, 0, 0, 0, 1, 1, 1 # 7 and 8 are replaced by 0 
0, 0, 0, 0, 0, 0, 0, 1, 1, 1 
0, 0, 0, 0, 0, 2, 2, 2, 1, 1 
4, 4, 4, 4, 2, 2, 2, 2, 1, 1 
4, 4, 4, 4, 2, 2, 2, 3, 3, 3 # 6 is gone, but 3 remains 
4, 4, 4, 4, 5, 5, 5, 3, 3, 5 
4, 4, 4, 4, 5, 5, 5, 5, 5, 5 
4, 4, 4, 4, 5, 5, 5, 5, 5, 5 

我已经研究过skimage形态学操作,包括binary closing,但没有似乎适用于我的用例。有什么建议么?

+0

什么角落情况下,像'0 0 1 2 2'? –

+1

@JonasAdler假设这里'm = 1',这样的平局就没有关系。运行左右可能会产生'0 0 0 2 2'形态操作,但'0 0 2 2 2'是罚款为好。 – BoltzmannBrain

+0

相关问题:https://stackoverflow.com/questions/46126409/numpy-filter-to-smooth-out-zero-regions @JonasAdler请大家看看如果可以的话,谢谢! – BoltzmannBrain

回答

0

您可以通过在与每个标签对应的布尔区域上执行二进制扩展来执行此操作。通过这样做,你会发现每个地区的邻居数量。使用这个,你可以根据需要替换值。

举一个例子代码:

import numpy as np 
import scipy.ndimage 

m = 5 

arr = [[0, 0, 0, 0, 0, 0, 0, 1, 1, 1], 
     [0, 0, 0, 0, 0, 0, 0, 1, 1, 1], 
     [0, 0, 7, 8, 0, 0, 0, 1, 1, 1], 
     [0, 0, 0, 0, 0, 0, 0, 1, 1, 1], 
     [0, 0, 0, 0, 0, 2, 2, 2, 1, 1], 
     [4, 4, 4, 4, 2, 2, 2, 2, 1, 1], 
     [4, 6, 6, 4, 2, 2, 2, 3, 3, 3], 
     [4, 6, 6, 4, 5, 5, 5, 3, 3, 5], 
     [4, 4, 4, 4, 5, 5, 5, 5, 5, 5], 
     [4, 4, 4, 4, 5, 5, 5, 5, 5, 5]] 
arr = np.array(arr) 
nval = np.max(arr) + 1 

# Compute number of occurances of each number 
counts, _ = np.histogram(arr, bins=range(nval + 1)) 

# Compute the set of neighbours for each number via binary dilation 
c = np.array([scipy.ndimage.morphology.binary_dilation(arr == i) 
       for i in range(nval)]) 

# Loop over the set of arrays with bad count and update them to the most common 
# neighbour 
for i in filter(lambda i: counts[i] < m, range(nval)): 
    arr[arr == i] = np.argmax(np.sum(c[:, arr == i], axis=1)) 

这给预期的结果:

>>> arr.tolist() 
[[0, 0, 0, 0, 0, 0, 0, 1, 1, 1], 
[0, 0, 0, 0, 0, 0, 0, 1, 1, 1], 
[0, 0, 0, 0, 0, 0, 0, 1, 1, 1], 
[0, 0, 0, 0, 0, 0, 0, 1, 1, 1], 
[0, 0, 0, 0, 0, 2, 2, 2, 1, 1], 
[4, 4, 4, 4, 2, 2, 2, 2, 1, 1], 
[4, 4, 4, 4, 2, 2, 2, 3, 3, 3], 
[4, 4, 4, 4, 5, 5, 5, 3, 3, 5], 
[4, 4, 4, 4, 5, 5, 5, 5, 5, 5], 
[4, 4, 4, 4, 5, 5, 5, 5, 5, 5]] 
+0

这似乎像一个魅力工作,谢谢!乍一看,我会做的唯一改变是适用于使用迭代器 - 'xrange'和'itertools.ifilter'。 – BoltzmannBrain

+0

此外,在实践中运行,直到收敛当W /更大的阵列我发现膨胀运算效果更好W/ARG'迭代= -1'。 – BoltzmannBrain