Rob*_*lor 6 python arrays numpy image-processing scipy
我有一个numpy数组,我希望将其划分为具有唯一ID的离散区域,如下所示:

通常对于这样的事情,我会使用scipy.ndimage.label为离散blob生成唯一的id,但是在这种情况下我有几个非常大的连续区域,我也希望将它们分割成更小的独特区域,理想情况是当它们只是连接时通过1个小区的连接到他们的邻居.为了说明,这是一个示例数组,我在运行scipy.ndimage.label时获得的结果,以及我想要的结果:
import numpy as np
import scipy.ndimage as ndimage
import matplotlib.pyplot as plt
# Sample study area array
example_array = np.array([[0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1],
[0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0],
[1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1],
[1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1],
[1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
[1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0],
[1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0],
[1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
# Identify discrete regions and assign unique IDs
current_output, num_ids = ndimage.label(example_array, structure=np.ones((3,3)))
# Plot outputs
plt.imshow(example_array, cmap="spectral", interpolation='nearest')
plt.imshow(current_output, cmap="spectral", interpolation='nearest')
Run Code Online (Sandbox Code Playgroud)

细胞的具体编号和分裂不是重要的; 任何类似上面最后一个情节的东西都可以.到目前为止,我最好的尝试是使用形态学图像处理来首先侵蚀我的阵列,运行scipy.ndimage.label然后扩张,但这有消除所有单细胞区域或细线性特征(其中有的)的不幸副作用许多).
非常感谢任何想法!
最简单的方法可能是在 SciPy 标签之前应用以下前置内核(以 2,2 作为原点,“?”可以是 0 或 1):
IF |? 1 ?| OR |? 0 ?| THEN origin(x,y) == 0
|0 1 0| |1 1 1|
|? 1 ?| |? 0 ?|
Run Code Online (Sandbox Code Playgroud)
执行:
import numpy as np
import scipy.ndimage as ndimage
import matplotlib.pyplot as plt
# Sample study area array
example_array = np.array([[0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1],
[0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0],
[1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1],
[1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1],
[1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
[1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0],
[1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0],
[1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
# Get array shape
row_count, column_count = example_array.shape
# Iterate through kernel origins
for (x,y), value in np.ndenumerate(example_array):
# Skip first and last rows and columns because kernel would be out of bounds
if not (x == 0
or x == row_count-1
or y == 0
or y == column_count-1):
# Extract kernel
kernel = example_array[x-1:x+2, y-1:y+2]
# Apply IF |? 1 ?| OR |? 0 ?| THEN origin(x,y) == 0
# |0 1 0| |1 1 1|
# |? 1 ?| |? 0 ?|
if ((kernel[1,0:3]).all() == 1 and kernel[0,1] == 0 and kernel[2,1] == 0
or (kernel[0:3,1]).all() == 1 and kernel[1,0] == 0 and kernel[1,2] == 0):
example_array[x,y] = 0
# Identify discrete regions and assign unique IDs
current_output, num_ids = ndimage.label(example_array, structure=np.ones((3,3)))
# Plot outputs
plt.imshow(example_array, cmap="spectral", interpolation='nearest')
plt.imshow(current_output, cmap="spectral", interpolation='nearest')
Run Code Online (Sandbox Code Playgroud)
结果:

| 归档时间: |
|
| 查看次数: |
1700 次 |
| 最近记录: |