首页 > 解决方案 > 如何使用索引定义数组中的值作为索引来定义数组中的值

问题描述

我正在尝试对图像进行复杂的转换,为了简单起见,创建了一个新图像,其中位置 (x, y) 的每个像素都定义为位置 (X(x), Y(x))原始图像,其中 X() 和 Y() 是确定转换结果来自原始图像的哪个像素的函数。目前,我只是遍历 x 和 y 的每个值并以这种方式分配像素颜色,但它太慢了,我一直在尝试使用数组索引但它不起作用。

这是我目前的工作解决方案,但如果没有迭代,我无法找到另一种方法:

我首先创建一个基本索引数组(我不知道它是否有实际名称),其中位置 (x, y) 的每个值都等于 (x, y)

index arr:
[ [[0 0][0 1][0 2]]
  [[1 0][1 1][1 2]]
  [[2 0][2 1][2 2]] ]

(如果它只是一个 3x3 数组,这将是一个示例,我正在处理整个图像)

然后我为转换创建一个新的索引数组。假设我的转换是围绕中心顺时针移动每个像素,新的转换定义数组将是:

transformed index array:
[ [[1 0][0 0][0 1]]
  [[2 0][1 1][0 2]]
  [[2 1][2 2][1 2]] ]

因此,新的转换图像将是 [0, 0] 处的像素将是原始图像中 [1, 0] 处的像素,而 [0, 1] 将是 [0, 0] 处的原始图像,依此类推,根据变换后的索引数组,比如下面

[ [1  2  3]           [ [4  1  2]
  [4  5  6]     ~~~>    [7  5  3]
  [7  8  9] ]           [8  9  6] ]

我的问题是,如果不遍历每个像素并从原始图像中分配应有的值,我就看不到以这种方式定义转换后的数组的方法。我尝试使用切片来做到这一点:

original_im = cv2.imread('im.jpg')
transposed_im = original_im.copy()     #copy original image then to get same shape and data type
transposed_im[:, :, :] = 0             #set all pixels to (0, 0, 0) before assigning them
transformed_index_arr = np.array([ [[1 0][0 0][0 1]]
                                   [[2 0][1 1][0 2]]
                                   [[2 1][2 2][1 2]] ])
transposed_im[:, :] = original_im[ transformed_index_arr[:, :]]

我知道这不起作用,但我通常理解“:”运算符的方式是“对于维度中的每个索引”,所以每当我尝试运行此代码时,它都会尝试使用整个 transformed_index_arr 列表作为切片original_im,即使我想要的只是相应的切片指向原始图像中像素的位置。

长话短说,我怎样才能在没有迭代的情况下解决这个问题?我不是 np 和数组索引方面的专家,无法解决这个问题,因此非常感谢任何帮助。我只是无法找到可以解释如何进行诸如此类的非线性转换的资源,或者解释如何使用此索引定义数组(可以调用它吗?)来定义转置图像。

标签: pythonarraysnumpyindexing

解决方案


这是一种方法:

import numpy as np
    
transformed_index_arr = np.array(
    [[[1, 0], [0, 0], [0, 1]], [[2, 0], [1, 1], [0, 2]], [[2, 1], [2, 2], [1, 2]]]
)

original_im = np.arange(9).reshape([3, 3]) + 1
transposed_im = original_im[
    (transformed_index_arr[..., 0], transformed_index_arr[..., 1])
]

这产生

>>> original_im 
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

>>> transposed_im
array([[4, 1, 2],
       [7, 5, 3],
       [8, 9, 6]])

推荐阅读