基于值将标量映射到数组:图像处理 2D 到 3D - NumPy / Python

Map scalars to arrays based on values : Image Processing 2D to 3D - NumPy / Python

给定一个形状为 (height, width) 的 Numpy 矩阵,我正在寻找创建另一个形状为 (height, width, 4) 的 Numpy 矩阵的最快方法,其中 4 表示 RGBA 值。我想做这个基于价值的;因此,对于第一个矩阵中的所有 0 值,我希望在第二个矩阵中的相同位置具有 [255, 255, 255, 0] 的值。

我想用 NumPy 做到这一点,而不需要像下面这样慢慢迭代:

for i in range(0, height):
    for j in range(0, width):
        if image[i][j] = 0:
            new_image[i][j] = [255, 255, 255, 0]
        elif image[i][j] = 1:
            new_image[i][j] = [0, 255, 0, 0.5]

如您所见,我正在创建一个矩阵,其中值 0 变为透明白色,1 变为绿色,alpha 为 0.5;有更快的 NumPy 解决方案吗?

我猜 numpy.where 应该能极大地帮助加快这个过程,但我还没有想出多重和许多价值翻译的正确实施。

为了更简洁的解决方案,尤其是在使用多个 标签时,我们可以利用 np.searchsorted 来追溯映射的值,就像这样 -

# Edit to include more labels and values here            
label_ar = np.array([0,1]) # sorted label array
val_ar = np.array([[255, 255, 255, 0],[0, 255, 0, 0.5]])

# Get output array
out = val_ar[np.searchsorted(label_ar, image)]

请注意,这假设来自 image 的所有唯一标签都在 label_ar

所以,现在假设我们在 image 中还有两个标签 23,就像这样 -

for i in range(0, height):
    for j in range(0, width):
        if image[i,j] == 0:
            new_image[i,j] = [255, 255, 255, 0]
        elif image[i,j] == 1:
            new_image[i,j] = [0, 255, 0, 0.5]
        elif image[i,j] == 2:
            new_image[i,j] = [0, 255, 255, 0.5]
        elif image[i,j] == 3:
            new_image[i,j] = [255, 255, 255, 0.5]

我们将相应地编辑标签和值并使用相同的 searchsorted 解决方案 -

label_ar = np.array([0,1,2,3]) # sorted label array
val_ar = np.array([
    [255, 255, 255, 0],
    [0, 255, 0, 0.5],
    [0, 255, 255, 0.5],
    [255, 255, 255, 0.5]])

你是对的 np.where 你就是这样解决这个问题的。矢量化函数在哪里,所以它应该比您的解决方案快得多。

我在这里假设它没有我知道的 elif,但您可以通过嵌套 where 语句来解决这个问题。

 new_image = np.where(
           image == 0,
           [255, 255, 255, 0],
           np.where(
                image == 1,
                [0, 255, 0, 0.5],
                np.nan
           )
      )