【问题标题】:Can't reshape the numpy array containing PNG images无法重塑包含 PNG 图像的 numpy 数组
【发布时间】:2018-02-17 12:22:30
【问题描述】:

我已经使用 Python 中的 Keras 库训练了一个手写图像分类器。最初,我使用标准 MNIST 数据集进行训练和测试。但是现在我想用我自己的数据集进行测试,其中所有图片的大小都是900*1200*3而不是28*28*1

所以我需要在测试之前重塑所有图像。我正在使用以下代码来重塑,但它给出了错误。

代码:

bb =  lol.reshape(lol.shape[0], 28, 28, 1).astype('float32')

lol 是我的 numpy 数组,其中包含 55 张形状为 (900,1200,3) 的图像

错误日志如下:

ValueError                                Traceback (most recent call last)
<ipython-input-46-87da95da73e9> in <module>()
     24 #     # you can show every image
     25 #     img.show()
---> 26 bb =  lol.reshape(lol.shape[0], 28, 28, 1).astype('float32')
     27 # model = loaded_model
     28 # classes = model.predict(bb)

ValueError: cannot reshape array of size 178200000 into shape (55,28,28,1)

那我做错了什么?即使将大图像调整为 28*28 的非常小的图像,我也能得到准确的预测吗?感谢帮助。

【问题讨论】:

  • 您不应该更改:lol.reshape(lol.shape[0], 28, 28, 1).astype('float32') 以使用新的图像形状,即900 x 1200x 3
  • 900 x 1200x 3 是我目前的形状。我想重塑28,28,1
  • 你知道reshape是做什么的吗?
  • 您无法在大小为 55 x 28 x 28 x 3 的对象中重塑大小为 55 x 900 x 1200 x 3 的对象而不丢失数据。您需要调整图像大小,而不是重塑数组。
  • 是的,这是 RGB -> 灰度 (3 -> 1) + 调整大小。这不是 reshape 所做的。

标签: python arrays numpy machine-learning


【解决方案1】:

你做错了。您无法将 (55, 900, 1200, 3) 的数组重新整形为 (55, 28, 28, 1) 的数组,因为您试图在数组中存储 55*900*1200*3=178200000 个元素只能存储 55*28*28=43120 个元素。

你想做两件事:

1) 将您的 rgb 图像(由最后一个维度表示,即 3 个通道)转换为灰度(1 个通道)。最简单的方法是 (R+B+G)/3。所有与图像有关的 python 库(PIL、OpenCV、skimage、tensorflow、keras 等)都已经实现了。示例:

from skimage.color import rgb2gray
gray = rgb2gray(original)

2) 将图像大小从 900x1200 调整为 28x28。同样,您可以在所有主要的与图像相关的 python 库中执行此操作。示例:

from skimage.transform import resize
resized = resize(gray, (28,28))

现在,如果您想在所有 55 张图像中执行此操作,您可以编写一个函数来转换一张图像并将其映射到您的数组中,或者使用一个简单的 for 循环并一次填充一张图像的新数组。

在您的情况下,代码应如下所示:

num_images = lol.shape[0] # 55 in your case
resized_images = np.zeros(shape=(num_images, 28, 28, 1)) # your final array
for i in range(num_images):
    gray = rgb2gray(lol[i,:,:,:]) # gray.shape should be (900,1200,1)
    resized = resize(gray, (28,28)) # resized.shape should be (28,28,1)
    resized_images[i,:,:,:] = resized # resized_images.shape should be (55,28,28,1)

【讨论】:

  • 感谢重播。但是在执行第二步之后,当我打印resized 的形状时,它会给出28*28*1200,但我需要的是28*28*1
  • 灰度数组的形状是什么?
  • 55,1200,900
  • 这些函数一次需要一个图像才能工作。我编辑了我的帖子以包括如何在您的情况下执行此操作。我还没有测试过,如果它不起作用,告诉我,我会修复它。
【解决方案2】:

单独处理每张图像会更直观,这也将为您提供保存某些信息的最佳机会。

尝试使用 PIL 库:

import numpy
from PIL import Image

lol = numpy.zeros((55,900,1200,3),dtype=numpy.uint8)
new_array = numpy.zeros((lol.shape[0],28,28),dtype=numpy.float32)

for i in range(lol.shape[0]):
    img = Image.fromarray(lol[i])
    img_resize = img.resize((28,28))
    img_mono = img_resize.convert('L')
    arr = numpy.array(img_mono,dtype=numpy.uint8)
    new_array[i] = arr

【讨论】:

    猜你喜欢
    • 2020-12-21
    • 2013-12-13
    • 1970-01-01
    • 2020-08-29
    • 2016-05-22
    • 1970-01-01
    • 2020-11-16
    • 1970-01-01
    相关资源
    最近更新 更多