python - 使用 Image.fromarray() 时元组索引超出 PIL 范围
问题描述
我正在尝试将一些 CIFAR10 图像数据处理成图像图块,以便在黑色画布上使用 PIL 进行绘图。在从训练有素的模型中提取特征时,我已经成功地做到了这一点,但是IndexError: Tuple Index out of range
在使用 Image.fromarray 时我不断得到。
我的特征被塑造成形状(10000,3072)的测试数据。数据是 32x32x3 图像。我加载了 cifar10 数据,然后将数据展平,但不断收到此错误。
这是我的代码。其中一些是从https://medium.com/@pslinge144/representation-learning-cifar-10-23b0d9833c40借来的
import numpy as np
from sklearn.manifold import TSNE
from time import time
from pathlib import Path
from PIL import Image
from time import time
from keras.datasets import cifar10
# Load the raw CIFAR-10 data
_, (X_test, y_test) = cifar10.load_data()
# normalize the xtest data
X_test = X_test.astype('float32')
X_test /= 255.0
features = X_test # this is (10000, 32, 32, 3) numpy array
features = np.reshape(features, (10000, 3072)) # flatten to 2d array
print(features.shape)
perplexities = [5, 30, 50, 100]
for perplexity in perplexities:
print("Starting t-SNE on images now!")
tsne = TSNE(n_components = 2, init = 'random', random_state = 0, perplexity = perplexity, learning_rate = 200).fit_transform(features)
tx, ty = tsne[:,0], tsne[:,1] # grab tsne first and 2nd dimensions
# min max normalize for plotting
tx = (tx-np.min(tx)) / (np.max(tx) - np.min(tx))
ty = (ty-np.min(ty)) / (np.max(ty) - np.min(ty))
width = 4000
height = 3000
max_dim = 100
full_image = Image.new('RGB', (width, height))
for idx, x in enumerate(features):
tile = Image.fromarray(np.uint8(x * 255), 'RGB') # rescale pixel values to [0,255] scale
rs = max(1, tile.width / max_dim, tile.height / max_dim)
tile = tile.resize((int(tile.width / rs),int(tile.height / rs)),Image.ANTIALIAS)
full_image.paste(tile, (int((width-max_dim) * tx[idx]),int((height-max_dim) * ty[idx])))
plots_output_path = Path('../data/processed/tSNE_plots').resolve()
filename = "tsne_perplex%d_plot.png" % (perplexity)
fullpath = plots_output_path.joinpath(filename).resolve()
full_image.save(str(fullpath))
这是错误:
Traceback (most recent call last):
File "tSNE_image_thumbnail.py", line 80, in <module>
tSNE_image(x_test, 1000, 200, plots_output_path, 2)
File "tSNE_image_thumbnail.py", line 56, in tSNE_image
tile = Image.fromarray(np.uint8(x * 255), 'RGB')
File "/home/zw/src/image_classification_ML/venv/lib/python3.8/site-packages/PIL/Image.py", line 2728, in fromarray
size = shape[1], shape[0]
IndexError: tuple index out of range
同样,当从我的 CNN 模型中提取我的特征并将其用于形状 (10000, 512) 密集层时,此代码工作正常。不知道为什么这会给我带来问题。有任何想法吗?提前致谢。
解决方案
您在行中提供长度为“3072”的数组
tile = Image.fromarray(np.uint8(x * 255), 'RGB')
只需调用np.uint8(x * 255).shape
一个 x 来验证它,它会返回(3072,)
.
但是对于“RGB”图像,您需要 3 维,而不仅仅是 1。
因此,您会收到错误消息tuple index out of range
,因为需要一个包含三个条目而不仅仅是一个条目的数组。
这意味着您需要一个包含三个条目的元组,而不是您的 (3072,),例如 (8,96,4),它将您的 3072 个值的一维数组映射到8 x 96 x 4
(=3072) 个值的矩阵。
因此,您可以将代码中的行更改为
tile = Image.fromarray(np.uint8(x).reshape(8,96,4),'RGB')
但最后,您应该根据图像尺寸定义形状。
推荐阅读
- ruby-on-rails - 使用每当 Rails 和 Docker 的 Cron - 作业未触发
- python - 为第一个数据帧的每一列计算两个数据帧的差异
- python - 使用 seaborn 绘制条形图
- selenium - 当我期望 false 时,Selenium isDisplayed() 返回 NoSuchElementException
- angular - 向前导航到重复路径,但具有离子和角度的独立页面
- json - 使用 Gson 将带有 under_score 的 JSON 属性转换为带有 lowerCamel 属性的 DTO
- keras - Keras 多输入一个共享嵌入层
- c++ - 为什么我的文件不应该被覆盖?
- python - 使用库替换python中的列值
- node.js - Azure 服务总线主题:为什么消息似乎被接收者吃掉了?