1. 碰见 numpy.transpose 用于高维数组时挺让人费解,通过分析和代码验证,发现 transpose 用法还是很简单的。说白了就是映射坐标轴
2. 举个例子:
x = np.arange(12).reshape((2,3,2))
创建一个2 * 3 * 2的数组:
使用 numpy.transpose ()进行变换,其实就是交换了坐标轴,如:x.transpose(1, 2, 0)
,其实就是将x第二维度挪到第一维上,第三维移到第二维上,原本的第一维移动到第三维上,最后的shape为:(3,2,2)
3. 分析原理
原先的数据的索引和数据对应情况为:
x[0][0][0] = 0 x[1][0][0] = 6
x[0][0][1] = 1 x[1][0][1] = 7
x[0][1][0] = 2 x[1][1][0] = 8
x[0][1][1] = 3 x[1][1][1] = 9
x[0][2][0] = 4 x[1][2][0] = 10
x[0][2][1] = 5 x[1][2][1] = 11
交换数据的索引,对应的值还是不变,即交换了坐标轴,如[0][2][1] —>[2][1][0]
x[0][0][0] = 0 x[0][0][1] = 6
x[0][1][0] = 1 x[0][1][1] = 7
x[1][0][0] = 2 x[1][0][1] = 8
x[1][1][0] = 3 x[1][1][1] = 9
x[2][0][0] = 4 x[2][0][1] = 10
x[2][1][0] = 5 x[2][1][1] = 11
根据变换后的索引进行归类
[
[[0, 6],
[1, 7]],
[[2, 8],
[3, 9]],
[[4, 10],
[5, 11]]
]
4. 再进行深思
例子中,我们使用的shape是(2, 3, 2),可以理解成:2通道的图片,每张图层是3 * 2大小
,正常渲染是先把第一个通道的图片把3 * 2个像素点绘制,在把第二个通道的3 * 2像素绘制。
在使用transpose(1, 2, 0)后,新的数据是shape是(3,2,2),可以理解成每张图层是3 * 2大小,2通道的图片
,原先的是先绘制一个通道数据,如今变换后的数据是每次将一个坐标的不同通道的像素进行一次性绘制。
如图:
打消了我对transpose影响图片呈现效果的疑虑
5. 来段代码测试一下,看看变化
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
from torchvision import transforms
%matplotlib inline
img_path = "./a.jpg"
# 对img_torch输出也是原图
img_torch = transforms.ToTensor()(Image.open(img_path))
resize = img_torch.numpy().transpose(1,2,0)
plt.imshow(resize)
plt.show()