Python Can';t重塑包含PNG图像的numpy数组

Python Can';t重塑包含PNG图像的numpy数组,python,arrays,numpy,machine-learning,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个形状图像(9001200,3)

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

所以我需要在测试之前重塑所有的图像。我使用下面的代码来重塑,但它会产生错误

代码:

bb =  lol.reshape(lol.shape[0], 28, 28, 1).astype('float32')
其中
lol
是我的numpy数组,包含55个形状图像
(9001200,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)
ValueError回溯(最近一次调用)
在()
24##你可以展示每一张图片
25#img.show()
--->26 bb=lol.shape(lol.shape[0,28,28,1).aType('float32'))
27#模型=加载的#模型
28类=模型预测(bb)
ValueError:无法将大小为178200000的数组重塑为形状(55,28,28,1)

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

单独处理每个图像会更直观,这也会给您保留某些信息的最佳机会

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

单独处理每个图像会更直观,这也会给您保留某些信息的最佳机会

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

你所做的是错误的。您无法将(55900、1200、3)的数组重塑为(55、28、28、1)的数组,因为您试图在只能存储55*28*28=43120个元素的数组中存储55*900*1200*3=178200000个元素

您需要做两件事:

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

from skimage.color import rgb2gray
gray = rgb2gray(original)
from skimage.transform import resize
resized = resize(gray, (28,28))
2)将图像大小从900x1200调整为28x28。同样,您可以在所有主要的与图像相关的python库中执行此操作。例如:

from skimage.color import rgb2gray
gray = rgb2gray(original)
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)

你所做的是错误的。您无法将(55900、1200、3)的数组重塑为(55、28、28、1)的数组,因为您试图在只能存储55*28*28=43120个元素的数组中存储55*900*1200*3=178200000个元素

您需要做两件事:

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

from skimage.color import rgb2gray
gray = rgb2gray(original)
from skimage.transform import resize
resized = resize(gray, (28,28))
2)将图像大小从900x1200调整为28x28。同样,您可以在所有主要的与图像相关的python库中执行此操作。例如:

from skimage.color import rgb2gray
gray = rgb2gray(original)
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)


您是否应该更改:
lol.respore(lol.shape[0],28,28,1)。astype('float32')
使用新的图像形状,即
900 x 1200x 3
900 x 1200x 3
是我当前的形状。我想在
28,28,1
中重塑你知道
重塑
做什么吗?在
55 x 28 x 28 x 3
大小的对象中,你不能重塑大小为
55 x 900 x 1200 x 3
的对象而不丢失数据。您需要调整图像的大小,而不是调整阵列的形状。是的,这是RGB->灰度(3->1)+调整大小。这不是整形所做的。你不应该改变:
lol.respore(lol.shape[0],28,28,1)。astype('float32')
使用新的图像形状,即
900 x 1200x 3
900 x 1200x 3
是我当前的形状。我想在
28,28,1
中重塑你知道
重塑
做什么吗?在
55 x 28 x 28 x 3
大小的对象中,你不能重塑大小为
55 x 900 x 1200 x 3
的对象而不丢失数据。您需要调整图像的大小,而不是调整阵列的形状。是的,这是RGB->灰度(3->1)+调整大小。这不是重塑所做的。谢谢重播。但在执行第二步后,当我打印大小调整后的
形状时,它会给出
28*28*1200
,但我需要的是
28*28*1
。灰度数组的形状是什么?它是551200900。函数每次需要一个图像才能工作。我编辑了我的帖子,在你的案例中加入了如何做到这一点。我还没有测试它,如果它不工作,告诉我,我会修复它。谢谢重播。但在执行第二步后,当我打印大小调整后的
形状时,它会给出
28*28*1200
,但我需要的是
28*28*1
。灰度数组的形状是什么?它是551200900。函数每次需要一个图像才能工作。我编辑了我的帖子,在你的案例中加入了如何做到这一点。我还没有测试过,如果它不工作,告诉我,我会修复它。