使用矩阵来通知像素应该打开或关闭的位置(Numpy)



我不知道该怎么说。我确信有一个操作描述了我试图做的事情——我只是没有太多操作图像阵列的经验。

我有一个1和0的2D数组(矩阵(,它指定一组像素是rbg中的颜色[255255255]还是颜色[0,0,0]。看起来这应该是一个简单的乘法运算。我应该能够将我的颜色乘以1和0的矩阵来制作图像,但我尝试过的所有点积和矩阵乘法都失败了。

下面是一个简单的例子,我的2D numpy数组和

# 2D pixels array
[[0,1],
[1, 1]]
# rbg array
[[255,255,255]]

我想要的是下面的3D阵列

[[[0,0,0],[255,255,255]],
[[255,255,255], [255,255,255]]]

该阵列的形状为2X2X3。

以下是可重复性的阵列,让任何愿意提供帮助的人都能轻松使用。

pixel = np.array([0,1,1,1]).reshape(2,2)
rgb = np.array([255,255,255]).reshape(1,3)

如何将像素重塑为3D矩阵并使用点?

pixel = np.array([0,1,1,1]).reshape(2,2,-1)
rgb = np.array([255,255,255]).reshape(1,3)
pixel.dot(rgb)

输出

array([[[  0,   0,   0],
[255, 255, 255]],
[[255, 255, 255],
[255, 255, 255]]])

如果按元素相乘矩阵,它们必须是可广播的,这意味着numpy可以将它们的大小转换为通用大小。来自numpy文档:

广播可以通过四条规则来理解:

  1. ndim小于最大ndim的输入数组的所有输入数组的形状都预加了1
  2. 输出形状的每个维度中的大小是该维度中所有输入大小的最大值
  3. 如果输入在特定维度中的大小与该维度中的输出大小匹配,或者其值正好为1,则可以在计算中使用该输入
  4. 如果输入的形状中的维度大小为1,则该维度中的第一个数据条目将用于该维度上的所有计算。换句话说,ufunc的步进机制将不会沿着该维度步进(该维度的步幅将为0(

所需的维度结构可以归结为三维数组,其中维度索引的含义为(y coordinate, x coordinate, colour channel),其中颜色通道索引为012(分别用于红色、绿色和蓝色(。

为了遵守上面显示的规则并获得上面解释的所需维度结构,我们需要确保我们的pixel数组具有三个维度,其中第三个维度的大小可以是1(参见规则3(。rgb数组可以保持不变,因为维度将自动添加到前面(请参见规则1(。由于规则2的原因,生成的数组在前两个维度将采用pixel数组的大小,在第三个维度将使用rgb数组的大小。

要向pixel数组添加第三个维度,可以使用reshape(如其他答案所示(或expand_dims函数。然后,您可以简单地在数组之间进行元素乘法,numpy将使用上面讨论的规则自动广播数组。参见以下示例:

>>> pixel = np.array([
...     [0, 1],
...     [1, 1]
... ])
>>> rgb = np.array([255, 255, 255])
>>> pixel.shape
(2, 2)
>>> rgb.shape
(3,)
>>> pixel = np.expand_dims(pixel, axis=2)  # add a third axis to get the correct shape
>>> pixel.shape
(2, 2, 1)
>>> image = rgb * pixel
>>> image.shape
(2, 2, 3)
>>> image
array([[[  0,   0,   0],
[255, 255, 255]],
[[255, 255, 255],
[255, 255, 255]]])

请注意,numpy打印数组的方式与您预期的有所不同,但您可以简单地验证数组是否与您想要的数组匹配:

>>> image[0, 0, :]
array([0, 0, 0])
>>> image[0, 1, :]
array([255, 255, 255])
>>> image[1, 0, :]
array([255, 255, 255])
>>> image[1, 1, :]
array([255, 255, 255])

矩阵相乘时,第一个矩阵的列必须与第二个矩阵的行匹配。第一个矩阵的行和第二个矩阵的列将是结果的新维度。

一个例子是,如果你有一个1x3矩阵,你乘以一个3x4矩阵。这是一个有效的乘法,因为第一个矩阵有3列,第二个矩阵有三行。结果将是1x4矩阵,因为第一个矩阵具有单行,第二个矩阵具有4列。

对于您的示例,我认为您需要一个嵌套循环来将像素数组中的每个元素与RBG值相乘。我不知道有什么好方法可以做到这一点,但我认为这可能会奏效。

pixel = np.array([0,1,1,1]).reshape(2,2)
rgb = np.array([255,255,255]).reshape(1,3)
arr = np.zeros((2,2,3))
for i in range(2):
for j in range(2):
for k in range(3):
arr[i][j][k] = pixel[i][j] * rgb[0][k]

最新更新