首页 > 解决方案 > 如何将一个轴与多个numpy数组匹配

问题描述

背景:我有一个具有三个缩小(W、H、C)的 rgb 图像,其中 C = 3。我想在此图像中屏蔽一些颜色,如 (0,0,255) 、 (0,255,255)。问题变成将图像的最后一个轴与我定义的颜色列表相匹配。color_list = [[255,0,0], [255,255,0], [255,0,255]] # just an example

用一种颜色很容易做到,

mask = np.all(image == [255,0,0], axis = 2)

但是如果我有多种颜色,我必须运行一个 for 循环。

masks = [np.all(image == color, axis = 2) for color in color_list]
mask = np.any(masks, axis=0)

问题:有什么优雅的方法可以获得多种颜色的面具?

标签: pythonnumpymergematch

解决方案


我有一种使用广播的方法,它更有效,因为它将在 C 中循环。基本上使数组具有可比性。一开始可能看起来很困难,但是一旦你知道它是如何工作的,这就是你将使用的全部[条件适用]....

import numpy as np
x = np.array([[[255,   0,   0],[  0, 255,   0], [  0, 255,   0], [  0, 255,   0]], [[255,   0,   0],[  0, 255,   0], [  0, 255,   0], [  0, 255,   0]]])
print(x.shape)
# (2, 4, 3)

color_list = np.array([[255,0,0], [255,255,0], [255,0,255]])
print(color_list.shape)
# (3, 3)

# make array compatible
x = x[:, :, np.newaxis, :]

### Analogy for interpreting broadcasting
# Here repeating is for analogy and does not mean it will allocate new copy of memory
# element wise comparision, possibler due to broadcast
# shape of x is (2, 4, 1, 3)
# By broadcasting conceptually x will be repeated along axis=2 this will make (2, 4, 3, 3)
# color_list will be repeated over (2, 4) making it (2, 4, 3, 3) and they will have same shape also the final shape after == will be (2, 4, 3, 3)
f1 = np.all(x[:, :, np.newaxis, :] == color_list, axis=3)
#array([[[ True, False, False],
#        [False, False, False],
#        [False, False, False],
#        [False, False, False]],
#
#       [[ True, False, False],
#        [False, False, False],
#        [False, False, False],
#        [False, False, False]]])

mask = np.any(f1, axis=2)

我们有形状的目标数组,(W, H, C) == (2, 4, 3)我们需要找到大小为 3 的数组color_list == [[255,0,0], [255,255,0], [255,0,255]]

理想情况下,我们希望这样做cross comparison,我的意思是,如果一侧有M和另一侧N条目,那么经过一些操作后,我们希望M * N得到结果。这似乎每 N 次重复 M 个条目并进行比较。虽然乍一看这似乎不可能,但 numpy 提供了广播。这将在概念上重复您的 for 循环之类的条目(实际上它的内存效率很高,它不会创建实际的副本)

所以我们需要广播,使这两个数组兼容,但它们不兼容,正如广播规则中提到的,形状是从右到左比较的,它们必须相同,或者其中一个必须为 1。

color_list 形状为 (3, 3),x 形状为 (2, 4, 3)。我们将在 x 中添加新轴以使其与x[:, :, np.newaxis, :]具有形状 (2, 4, 1, 3) 的广播兼容。现在两者都兼容,我们可以比较。

沿最后一个轴进行比较,即颜色通道轴 = 3,然后在最后一个轴上比较,其轴 = 2 将给出 (W, H) 布尔值,其中每个条目表示 True 如果颜色通道三元组存在于 中color_list

这种技术与给定两个点数组时的距离矩阵完全相同


推荐阅读