5

我正在运行这段代码

from PIL import Image
import numpy as np
im = Image.open("/Users/Hugo/green_leaves.jpg")
im.load()
height, widht = im.size
p = np.array([0,0,0])
for row in range(height):
     for col in range(widht):
         a = im.getpixel((row,col))
         p = np.append(a.asarray())

但我收到以下错误

Traceback (most recent call last):
   File "/Users/hugo/PycharmProjects/Meteo API/image.py", line 17, in <module>
     p = np.append(a.asarray())
 AttributeError: 'tuple' object has no attribute 'asarray'

你可以帮帮我吗?

4

2 回答 2

16

你提到了numpy。如果您想要图像的 numpy 数组,请不要遍历它,只需执行data = np.array(im).

例如

from PIL import Image
import numpy as np
im = Image.open("/Users/Hugo/green_leaves.jpg")
p = np.array(im)

通过反复追加来构建一个 numpy 数组是非常低效的。Numpy 数组不像 python 列表(python 列表很好地服务于这个目的!!)。它们是固定大小、同质、内存高效的数组。

如果您确实想通过附加来构建一个 numpy 数组,请使用一个列表(可以有效地附加到该列表),然后将该列表转换为一个 numpy 数组。

但是,在这种情况下,PIL 图像支持直接转换为 numpy 数组。

另外一点,我上面给出的示例并非 100% 等同于您的代码。 p将是 numbands(3 或 4)数组的高度乘以宽度,而不是原始示例中的 numpixels 乘 numbands 数组。

如果您想通过 numbands 将数组重塑为 numpixels,只需执行以下操作:

p = p.reshape(-1, p.shape[2])

(或等效地,p.shape = -1, p.shape[2]

这会将数组重塑为width*heightnumbands(3 或 4,取决于是否有 alpha 通道)数组。换句话说,图像中红色、绿色、蓝色、alpha 像素值的序列。这-1是一个占位符,它告诉 numpy 根据指定的其他尺寸计算第一个轴的适当形状。

于 2014-02-19T16:02:57.190 回答
2

初始化p为列表,并在for循环后将其转换为numpy数组:

p=[]
for row in range(height):
     for col in range(widht):
         a = im.getpixel((row,col))
         p.append(a)
p=np.asarray(p)

这将创建一个形状列表 (*, 3),与np.array(im).reshape(-1, 3). 因此,如果您需要这个,只需使用后一种形式;)

于 2014-02-19T16:01:12.593 回答