无法重塑包含PNG图像的numpy数组

时间:2017-09-08 14:27:14

标签: python arrays numpy machine-learning

我在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的非常小的图像,我能获得准确的预测吗?感谢帮助。

2 个答案:

答案 0 :(得分:2)

你在做什么是错的。您不能将(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)

答案 1 :(得分:0)

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

尝试使用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