【问题标题】:reshape an array of images重塑图像数组
【发布时间】:2016-05-20 01:07:29
【问题描述】:

我有 60000 个 train_images 作为形状 (28,28,60000) 矩阵引入。它是一个 numpy.ndarray。我想将其转换为一维图像数组,这意味着每个图像都表示为单行/数字数组,我想要 60000 个数组。换句话说,我想从 (28, 28, 60000) 到 (60000, 28*28)。在 python 中,它会是:

images_features = []
for image in images:
    imageLine = []
    for y in range(len(image)):
        for x in range(len(image[0])):
            imageLine.append(image[y][x])
    images_features.append(imageLine)

我该怎么做?我怀疑我需要使用 reshape ,但我不知道我该怎么做。

这就是我获取图像的方式:

data = scipy.io.loadmat('train.mat')


images = data["train_images"]

所以“图像”就是我所说的数组。

有人向我建议:

“您可能需要更改轴或将它们组合起来才能获得所需的功能。我建议您也绘制它们,以防图像最终横向显示。确保您勤于使用轴以避免进一步的问题。”

我不知道这里指的是什么“轴”以及如何考虑上面所说的。

谁能解释我需要做什么以及为什么? (它的作用)

【问题讨论】:

  • 如果你希望输出是一个 python 列表,可能是 images.reshape(-1).tolist()(或者没有 tolist() 否则)?
  • -1 有什么作用?我需要一个 1 x 28^2 x 60000 的数组。
  • 对不起,我看错了。 -1 完全压平矩阵(这不是你想要的)。你可以看看关于N-dimensional array的numpy文档
  • 如果我理解得很好,images.reshape(-1, 60000) 会完成这项工作吗?为您提供 60000 个具有 784 个值的特征。要将输出作为 60000 个功能的 python 列表:images.reshape(-1, 60000).T.tolist()
  • image.transpose(2,0,1)image.transpose(2,1,0)?

标签: python arrays numpy reshape


【解决方案1】:

由于这是通过 loadmat 实现的,(28,28,60000) 的形状是有意义的 - MATLAB 从最后一个索引开始迭代。

images.transpose()  # or images.T

对坐标轴重新排序,因此结果为(60000,28,28)。最后两个维度可以与重塑相结合

images.T.reshape(60000,28*28)
images.T.reshape(60000,-1)   # short hand

很多人需要转置 28x28 图像,例如

images.transpose([2,0,1])  # instead of the default [2,1,0]

.T 与 MATLAB '(或.')相同。

images 也可能是order='F'


octave:38> images=reshape(1:30,2,3,5);
octave:39> save test.mat -v7 images
octave:40> images
images =

ans(:,:,1) =

   1   3   5
   2   4   6

ans(:,:,2) =

    7    9   11
    8   10   12
....

我选择的测试尺寸很小,以便于区分不同的轴。

在 Ipython 会话中:

In [15]: data=io.loadmat('test.mat')

In [16]: data
Out[16]: 
{'__globals__': [],
 '__header__': 'MATLAB 5.0 MAT-file, written by Octave 3.8.2, 2016-02-10 05:19:18 UTC',
 '__version__': '1.0',
 'images': array([[[  1.,   7.,  13.,  19.,  25.],
        [  3.,   9.,  15.,  21.,  27.],
        [  5.,  11.,  17.,  23.,  29.]],

       [[  2.,   8.,  14.,  20.,  26.],
        [  4.,  10.,  16.,  22.,  28.],
        [  6.,  12.,  18.,  24.,  30.]]])}

In [18]: data['images'].T
Out[18]: 
array([[[  1.,   2.],
        [  3.,   4.],
        [  5.,   6.]],

       [[  7.,   8.],
        [  9.,  10.],
        [ 11.,  12.]],
....
In [19]: data['images'].transpose([2,0,1])
Out[19]: 
array([[[  1.,   3.,   5.],
        [  2.,   4.,   6.]],

       [[  7.,   9.,  11.],
        [  8.,  10.,  12.]],
 ....
In [22]: data['images'].transpose([2,1,0]).reshape(5,-1)
Out[22]: 
array([[  1.,   2.,   3.,   4.,   5.,   6.],
       [  7.,   8.,   9.,  10.,  11.,  12.],
 ...

【讨论】:

  • 所以我这样做:images = images.transpose().reshape(60000, -1)?
  • 如果是这样,我如何决定是使用默认转置还是使用 2、0、1?
  • 所以,从上面的例子来看,似乎 data['images'].transpose([2,1,0]).reshape(5,-1) 做了正确的事情,其中2,1,0 是转置的默认设置。
【解决方案2】:

我认为你只需要使用 reshape:

>>> images = np.ndarray([60000, 28, 28])
>>> images.shape
(60000, 28, 28)
>>> images_rs = images.reshape([60000, 28*28])
>>> images_rs.shape
(60000, 784)

【讨论】:

  • 应该是images.reshape([60000, 28*28])还是images.reshape([28*28, 60000])?有什么区别?
  • 在我的 cmets 中,我使用 28, 28, 60000 的形状只是为了适合您在问题中所说的数字,但 reshape 不会抱怨,因为数组的大小没有改变(输出是使用60000, 28*28 而不是28*28, 60000 可能更有序。
  • 我认为如果你有 60000 张单独的图像,那么这应该是第一个维度。您将拥有一个包含 60000 个长度为 784 的数组的数组。在 (28*28 x 60000) 的情况下,您将拥有一个包含 784 个 (28*28) 个长度为 60000 的数组的数组。
  • 原来答案中建议的方式不能正常工作。
  • 结果矩阵的大小正确但内容不正确。
【解决方案3】:

你可以重塑train_images并通过绘制图像来验证它,

重塑:

train_features_images = train_images.reshape(train_images.shape[0],28,28) 

绘制图像:

import matplotlib.pyplot as plt
def show_images(features_images,labels,start, howmany):
    for i in range(start, start+howmany):
        plt.figure(i)
        plt.imshow(features_images[i], cmap=plt.get_cmap('gray'))
        plt.title(labels[i])
    plt.show()
show_images(train_features_images, labels, 1, 10)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-18
    • 2020-11-16
    • 2017-06-11
    • 2020-12-21
    • 2018-02-07
    • 2021-09-27
    • 2018-02-17
    相关资源
    最近更新 更多