如何在非二进制图像上使用 scipy.label
how to use scipy.label on a non-binary image
我需要标记一个已经分类的 img。问题是,图像不是二进制的,我需要分别计算不同值的相邻补丁。
考虑以下数据集:
import numpy as np
data = np.zeros((6,6), dtype=np.uint16)
data[2:4, 2:4] = 10
data[4, 4] = 10
data[:2, :3] = 22
data[0, 5] = 22
data
>>>
array([[22, 22, 22, 0, 0, 22],
[22, 22, 22, 0, 0, 0],
[0, 0, 10, 10, 0, 0],
[0, 0, 10, 10, 0, 0],
[0, 0, 0, 0, 10, 0],
[0, 0, 0, 0, 0, 0]], dtype=uint16)
我想获得(具有 8 个相邻结构元素的)以下内容:
array([[1, 1, 1, 0, 0, 3],
[1, 1, 1, 0, 0, 0],
[0, 0, 2, 2, 0, 0],
[0, 0, 2, 2, 0, 0],
[0, 0, 0, 0, 2, 0],
[0, 0, 0, 0, 0, 0]], dtype=uint16)
但是使用 scipy.label 函数我得到了完全不同的结果:
from scipy import ndimage as ndi
s = ndi.generate_binary_structure(2,2)
labeled_array, num_features = ndi.label(data, structure=s)
labeled_array
>>>
array([[1, 1, 1, 0, 0, 2],
[1, 1, 1, 0, 0, 0],
[0, 0, 1, 1, 0, 0],
[0, 0, 1, 1, 0, 0],
[0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0]], dtype=int16)
那么有没有什么技巧可以区分不同值的补丁?
获取唯一值列表uv
,然后用订单号替换每个唯一值(第一个值用 0,第二个值用 1,依此类推)
uv = np.unique(data)
res = np.select([data==i for i in uv], range(len(uv)))
示例:
import numpy as np
data = np.zeros((6,6), dtype=np.uint16)
data[2:4, 2:4] = 10
data[4, 4] = 10
data[:2, :3] = 22
data[0, 5] = 32
结果:
array([[2, 2, 2, 0, 0, 3],
[2, 2, 2, 0, 0, 0],
[0, 0, 1, 1, 0, 0],
[0, 0, 1, 1, 0, 0],
[0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0]])
UPDATE 我看到您更改了问题中的数据。在这种情况下,它不再是已经分类的图像,因为 data[0,5]
不能是 22
如果它没有与所有其他 22
链接。
所以在这种情况下,我猜你需要像这样分别为数据中的每个唯一条目做标签:
import numpy as np
from scipy import ndimage as ndi
data = np.zeros((6,6), dtype=np.uint16)
data[2:4, 2:4] = 10
data[4, 4] = 10
data[:2, :3] = 22
data[0, 5] = 22
uv = np.unique(data)
s = ndi.generate_binary_structure(2,2)
cum_num = 0
result = np.zeros_like(data)
for v in uv[1:]:
labeled_array, num_features = ndi.label((data==v).astype(int), structure=s)
result += np.where(labeled_array > 0, labeled_array + cum_num, 0).astype(result.dtype)
cum_num += num_features
数据:
[[22 22 22 0 0 22]
[22 22 22 0 0 0]
[ 0 0 10 10 0 0]
[ 0 0 10 10 0 0]
[ 0 0 0 0 10 0]
[ 0 0 0 0 0 0]]
结果:
[[2 2 2 0 0 3]
[2 2 2 0 0 0]
[0 0 1 1 0 0]
[0 0 1 1 0 0]
[0 0 0 0 1 0]
[0 0 0 0 0 0]]
我需要标记一个已经分类的 img。问题是,图像不是二进制的,我需要分别计算不同值的相邻补丁。
考虑以下数据集:
import numpy as np
data = np.zeros((6,6), dtype=np.uint16)
data[2:4, 2:4] = 10
data[4, 4] = 10
data[:2, :3] = 22
data[0, 5] = 22
data
>>>
array([[22, 22, 22, 0, 0, 22],
[22, 22, 22, 0, 0, 0],
[0, 0, 10, 10, 0, 0],
[0, 0, 10, 10, 0, 0],
[0, 0, 0, 0, 10, 0],
[0, 0, 0, 0, 0, 0]], dtype=uint16)
我想获得(具有 8 个相邻结构元素的)以下内容:
array([[1, 1, 1, 0, 0, 3],
[1, 1, 1, 0, 0, 0],
[0, 0, 2, 2, 0, 0],
[0, 0, 2, 2, 0, 0],
[0, 0, 0, 0, 2, 0],
[0, 0, 0, 0, 0, 0]], dtype=uint16)
但是使用 scipy.label 函数我得到了完全不同的结果:
from scipy import ndimage as ndi
s = ndi.generate_binary_structure(2,2)
labeled_array, num_features = ndi.label(data, structure=s)
labeled_array
>>>
array([[1, 1, 1, 0, 0, 2],
[1, 1, 1, 0, 0, 0],
[0, 0, 1, 1, 0, 0],
[0, 0, 1, 1, 0, 0],
[0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0]], dtype=int16)
那么有没有什么技巧可以区分不同值的补丁?
获取唯一值列表uv
,然后用订单号替换每个唯一值(第一个值用 0,第二个值用 1,依此类推)
uv = np.unique(data)
res = np.select([data==i for i in uv], range(len(uv)))
示例:
import numpy as np
data = np.zeros((6,6), dtype=np.uint16)
data[2:4, 2:4] = 10
data[4, 4] = 10
data[:2, :3] = 22
data[0, 5] = 32
结果:
array([[2, 2, 2, 0, 0, 3],
[2, 2, 2, 0, 0, 0],
[0, 0, 1, 1, 0, 0],
[0, 0, 1, 1, 0, 0],
[0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0]])
UPDATE 我看到您更改了问题中的数据。在这种情况下,它不再是已经分类的图像,因为 data[0,5]
不能是 22
如果它没有与所有其他 22
链接。
所以在这种情况下,我猜你需要像这样分别为数据中的每个唯一条目做标签:
import numpy as np
from scipy import ndimage as ndi
data = np.zeros((6,6), dtype=np.uint16)
data[2:4, 2:4] = 10
data[4, 4] = 10
data[:2, :3] = 22
data[0, 5] = 22
uv = np.unique(data)
s = ndi.generate_binary_structure(2,2)
cum_num = 0
result = np.zeros_like(data)
for v in uv[1:]:
labeled_array, num_features = ndi.label((data==v).astype(int), structure=s)
result += np.where(labeled_array > 0, labeled_array + cum_num, 0).astype(result.dtype)
cum_num += num_features
数据:
[[22 22 22 0 0 22]
[22 22 22 0 0 0]
[ 0 0 10 10 0 0]
[ 0 0 10 10 0 0]
[ 0 0 0 0 10 0]
[ 0 0 0 0 0 0]]
结果:
[[2 2 2 0 0 3]
[2 2 2 0 0 0]
[0 0 1 1 0 0]
[0 0 1 1 0 0]
[0 0 0 0 1 0]
[0 0 0 0 0 0]]