numpy 从Image.open获得的数组,其中np.asarray是不可变的-“赋值目标是只读的”

koaltpgm  于 9个月前  发布在  其他
关注(0)|答案(6)|浏览(71)

我的目标是读取一组PNG文件,使用Image.open('filename')创建Image(s),并将它们转换为只有1和0的简单2D数组。PNG的格式为RGBA,大多数只有255和0作为值。在图像中,边缘通常是灰度值,这是我想在2D数组中避免的。
我使用np.asarray(Image)从图像中创建了2D数组,只获得了“红色”通道。在每个二维图像数组中,如果当前值不为零,我想将单元格值设置为1。
所以,我循环进入二维数组,检查单元格的值,并尝试将其设置为1。
它给我一个错误,指示数组是只读的。我读了几个堆栈溢出线程讨论np数组是不可变的,这仍然是一个有点不清楚。我用PIL和Numpy。

from PIL import Image
import numpy as np

相关代码:

prArray = [np.asarray(img)[:, :, 0] for img in problem_images]

for img in prArray:
    for x in range(184):
        for y in range(184):
            if img[x][y] != 0:
                img[x][y] = 1

最后一行出现错误“赋值目标为只读”。

smtd7mpg

smtd7mpg1#

检查数组是否可写,

>>> img.flags
  C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : True
  WRITEABLE : False
  ALIGNED : True
  UPDATEIFCOPY : False

如果WRITEABLE为false,则将其更改为

img.setflags(write=1)
qoefvg9y

qoefvg9y2#

由于numpy版本1.16.0,以下内容不再工作:

img = np.asarray(Image.open(filename))
img.setflags(write=1)

问题是,现在OWNDATA被设置为False,而你不能将WRITEABLE标志设置为True。因此,您只需执行以下操作:

img = np.array(Image.open(filename))

这将在将数组从Pillow对象转换为numpy数组时复制数组。然而,我在numpy1.16.0中测试了时间性能,并没有发现这两种方法之间有任何明显的差异。

5sxhfpxr

5sxhfpxr3#

在这种情况下,我认为你正在尝试编辑由另一个用户提供给你的图像,他/她使其不可编辑,这就是为什么你得到这个错误。对于您的情况,您可以尝试创建给定文件的副本,并使用.copy()对该文件进行更改。

img_copy = img.copy()
prArray = [np.asarray(img_copy)[:, :, 0] for img_copy in problem_images]

更重要的是,我认为我们大多数人都不想改变我们的原始图像,这就是为什么我总是使用.copy(),并建议您也这样做。

whlutmcx

whlutmcx4#

ValueError: cannot set WRITEABLE flag to True of this array array.setflags(write=1)

使用使用np.copy()复制数组跳过语句

vq8itlhq

vq8itlhq5#

我建议你停止在原始图像上做数学运算。您可以通过使用img.copy()来解决这个问题

img = plt.imread('../img/1.2.jpg')
img=img.copy()
qjp7pelc

qjp7pelc6#

我认为你不需要降级你的numpy版本。你只需要像这样复制原始图像:

img_copy = np.copy(img)

而且很有效!

相关问题