我想知道我是否有一个numpy数组中的图像,例如250x250x3(3个通道),是否可以使用np.where来快速找出大小为3的250x250数组中的任何一个是否等于[143 ,255、0]或由rgb表示的另一种颜色,并获得250x250布尔数组?
当我在代码中使用4x4x3进行尝试时,得到的结果是3x3数组,但我不确定该形状的来源。
import numpy as np
test = np.arange(4,52).reshape(4,4,3)
print(np.where(test == [4,5,6]))
-------------------------------------------
Result:
array([[0, 0, 0],
[0, 0, 0],
[0, 1, 2]])
What I'm trying to get:
array([[1, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]])
答案 0 :(得分:2)
为简单起见,假设我们正在寻找所有3个通道都等于1的所有位置。
np.random.seed(0)
a=np.random.randint(0,2,(3,5,5))
print(a)
np.where((a[0]==1)*(a[1]==1)*(a[2]==1))
此输出
[[[0 1 1 0 1]
[1 1 1 1 1]
[1 0 0 1 0]
[0 0 0 0 1]
[0 1 1 0 0]]
[[1 1 1 1 0]
[1 0 1 0 1]
[1 0 1 1 0]
[0 1 0 1 1]
[1 1 1 0 1]]
[[0 1 1 1 1]
[0 1 0 0 1]
[1 0 1 0 1]
[0 0 0 0 0]
[1 1 0 0 0]]]
(array([0, 0, 1, 2, 4], dtype=int64), array([1, 2, 4, 0, 1], dtype=int64))
确实有5个坐标,其中所有3个通道均等于1。 如果您想获得更易读的表示形式,请用
替换最后一行tuple(zip(*np.where((a[0]==1)*(a[1]==1)*(a[2]==1))))
这将输出
((0, 1), (0, 2), (1, 4), (2, 0), (4, 1))
是所有3个通道均等于1的所有5个位置。
请注意,(a[0]==1)*(a[1]==1)*(a[2]==1)
只是
array([[False, True, True, False, False],
[False, False, False, False, True],
[ True, False, False, False, False],
[False, False, False, False, False],
[False, True, False, False, False]])
您要查找的布尔表示形式。
如果要获取其他任何三元组,请说[143, 255, 0]
,只需使用(a[0]==143)*(a[1]==255)*(a[2]==0)
。
答案 1 :(得分:2)
您根本不需要np.where
(或任何特别复杂的东西)。您可以利用布尔数组的功能:
print(np.all(test == [4,5,6], axis=-1).astype(int))
# output:
# [[1 0 0 0]
# [0 0 0 0]
# [0 0 0 0]
# [0 0 0 0]]
等效的替代方法是使用logical_and
:
print(np.logical_and.reduce(test == [4,5,6], axis=-1).astype(int))
# output:
# [[1 0 0 0]
# [0 0 0 0]
# [0 0 0 0]
# [0 0 0 0]]
import numpy as np
np.random.seed(0)
# the subarray we'll search for
pattern = [143, 255, 0]
# generate a random test array
arr = np.random.randint(0, 255, size=(255,255,3))
# insert the pattern array at ~10000 random indices
ix = np.unique(np.random.randint(np.prod(arr.shape[:-1]), size=10000))
arr.reshape(-1, arr.shape[-1])[ix] = pattern
# find all instances of the pattern array (ignore partial matches)
loc = np.all(arr==pattern, axis=-1).astype(int)
# test that the found locs are equivalent to the test ixs
locix = np.ravel_multi_index(loc.nonzero(), arr.shape[:-1])
np.testing.assert_array_equal(np.sort(ix), np.sort(locix))
# test has been run, the above assert passes