为什么转置一个 numpy 数组将它旋转 90 度?

Why does transposing a numpy array rotate it 90 degrees?

我正在尝试从 lmdb dataset 中读取图像,对每个图像进行扩充,然后将它们保存到另一个 dataset 中以用于我的训练。
这些图像轴最初在保存到 lmdb dataset 时更改为 (3,32,32),因此为了增强它们,我不得不将它们转置回它们的实际形状。
问题是每当我尝试使用 matplotlibshow() 方法或 scipytoimage() 方法显示它们时,它们都会显示图像的旋转版本。 所以我们有:

img_set = np.transpose(data_train,(0,3,2,1))
#trying to display an image using pyplot, makes it look like this:  
plt.subplot(1,2,1)
plt.imshow(img_set[0])

使用 toimage 显示相同的图像:

现在,如果我不转置 data_trainpyplotshow() 会生成错误,同时 toimage() 显示图像好:

这里发生了什么?
当我将转置后的 data_train 提供给我的增强器时,我也得到了旋转的结果,就像前面的例子一样。
现在我不确定这是显示问题,还是实际图像确实旋转了!
我应该怎么办 ?

首先,仔细观察。转置阵列不旋转,而是在对角线上镜像(即交换 X 和 Y 轴)。

原形是(3,32,32),我解读为(RGB, X, Y)。但是,imshow 需要一个形状数组 MxNx3 - 颜色信息必须在最后一个维度。

通过转置数组,您可以颠倒维度的顺序:(RGB, X, Y) 变为 (Y, X, RGB)。这对 matplotlib 很好,因为颜色信息现在在最后一个维度中,但 X 和 Y 也被交换了。如果你想保留 X、Y 的顺序,你可以告诉 transpose to do so:

import numpy as np

img = np.zeros((3, 32, 64))  # non-square image for illustration

print(img.shape)  # (3, 32, 64)
print(np.transpose(img).shape)  # (64, 32, 3)
print(np.transpose(img, [1, 2, 0]).shape)  # (32, 64, 3)

当使用 imshow 显示图像时,请注意以下陷阱:

  1. 它将图像视为矩阵,因此数组的维度被解释为(ROW, COLUMN, RGB),相当于(VERTICAL, HORIZONTAL, COLOR) or (Y, X, RGB).

  2. 它改变了y轴的方向所以左上角是img[0, 0]。这与 matplotlib 的正常坐标系不同,其中 (0, 0) 是左下角。

示例:

import matplotlib.pyplot as plt

img = np.zeros((32, 64, 3))
img[1, 1] = [1, 1, 1]  # marking the upper right corner white

plt.imshow(img)

请注意,较小的第一维对应于图像的垂直方向。