Numpy中图像数据的储存与Tensor转化

        在写网络时,常常要自己导入数据和预处理,其中很关键的一点就是要将Numpy数据转化到torch.tensor,这里就牵扯到一个问题,在Np.array中,一张RGB图像的储存是按照[H,W,C]进行存储的,而在Torch中,图像是按照[C,H,W]进行存储,而且在进行torchvision.transforms.ToTensor中会自动将文件转存为[C,H,W], 我的疑问是:1.Numpy中数据是如何储存又该如何去读? 2. ToTensor操作后的数据和在Numpy中自行reshape为[C,H,W]是否一致?

        对于问题1,如果是三维的Numpy

import numpy as np


x3 = np.random.randint(0,10,(3,2,4))
print('>>> --------------------------3-D-------------------------------- <<<')
print(x3)
[print('the {}st layer is\n {}\n'.format(i,x3[:,:,i])) for i in range(4)] 

得到的结果为

x3

[[[5 6 1 7]
  [9 9 7 3]]

 [[6 6 8 6]
  [5 1 7 0]]

 [[8 5 7 0]
  [5 8 9 4]]]

若以图像去看这个三维nparray,有

the 0st layer is
 [[5 9]
 [6 5]
 [8 5]]

the 1st layer is
 [[6 9]
 [6 1]
 [5 8]]

the 2st layer is
 [[1 7]
 [8 7]
 [7 9]]

the 3st layer is
 [[7 3]
 [6 0]
 [0 4]]

可以发现对于3D-array, x3中遍历每一个块的第j列对应了图像第j层的逐行遍历。也即我们可以以这种角度去理解三维的np.array,经过ToTensor后,矩阵变为

tensor([[[5, 9],
         [6, 5],
         [8, 5]],

        [[6, 9],
         [6, 1],
         [5, 8]],

        [[1, 7],
         [8, 7],
         [7, 9]],

        [[7, 3],
         [6, 0],
         [0, 4]]], dtype=torch.int32)

也即在将原矩阵的第2维提到第0维时,并不改变图像。那么如果我们在np.array时就将3-D的矩阵转化为2-D,再转为Tensor后重新reshape为3-D,结果是否会有改变呢?

a = []
[a.append(x3[:,:,i].flatten().reshape(1,x3[:,:,0].size)) for i in range(3)]
aa = np.concatenate(a,axis=0)
tensor_aa = trans(aa).reshape(3,4,2)
# 检验两者是否相同
tensor_x3.equal(tensor_aa)

#输出:True,所以有时候为了避免三维图像转化时候忘记调channel位置,可以选择将其转化为二维。

        一个重点在于,导入数据时我们面对的不仅仅是三维,第四维数据Batch_size是存在的,此时就算拉直了原始数据降低了一维,输出的矩阵仍是三维的,那么为什么仅仅将三维变成二维的呢?如果我们选择直接将三维变成一维的,这样数据矩阵的大小就是data_sizeXimage_pixel_size

tensor_aaa = trans(aa.reshape(1,x3.size))
tensor_x3.equal(tensor_aaa.reshape(3,4,2))

#输出:True,这也证明我们可以将数据先拉直为1维转化为Tensor后再转化为3维。

        现在回答问题2,既然都是reshape,那么能否我提前将np.array变为[C,H,W]大小,这样得到的和[H,W,C]经过ToTensor后一致吗?结果是不一致的,大家自行进行以下这个操作,并与torch张量对比就可以看到。至于原因尚不清楚,欢迎对此有理解的朋友赐教。

        此外,值得一提的是,如果是以下的操作,结果表明此时进行reshape其实只是一个数据转化而已:

import torch
import numpy as np


a = torch.rand(10,3,7,8)
b = a.numpy()
im1 = a[0]
cvt_hwc = a.permute([0,2,3,1])
print('The size of cvt_hwc is:\t{}'.format(cvt_hwc.shape))
im2 = cvt_hwc[0]
im2_0 = im2[:,:,0]
im2[:,:,0].eq(im1[0])

 结果为:

tensor([[True, True, True, True, True, True, True, True],
        [True, True, True, True, True, True, True, True],
        [True, True, True, True, True, True, True, True],
        [True, True, True, True, True, True, True, True],
        [True, True, True, True, True, True, True, True],
        [True, True, True, True, True, True, True, True],
        [True, True, True, True, True, True, True, True]])

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值